home *** CD-ROM | disk | FTP | other *** search
/ Software of the Month Club 1997 April / Software of the Month Club 1997 April.iso / pc / dos / games / fastmaze / hexmaze.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-10-04  |  99.5 KB  |  2,596 lines

  1. /*
  2.                                FMAZ41 -- Maze Game
  3.  
  4.                               Version 4.1 (10/4/95)
  5.  
  6.  
  7.      Generate and solve mazes on your VGA (or better) display.
  8.  
  9.      The mazes are displayed in three dimensions.
  10.  
  11.      You will be prompted for the number of columns, the tilt, the number of
  12. mazes to be tried before one is selected for display, and a random number seed.
  13.  
  14.      While the maze is being selected, a spinning cursor is displayed.
  15.  
  16.      After the maze is displayed, you may use the Home, PgUp, PgDn, End, up 
  17. arrow, and down arrow keys to solve it.  Press "Q" to quit or press "S" to have
  18. the computer solve the maze.
  19.  
  20.      After the maze is solved, you must press some key to continue.
  21.  
  22.      Each maze has exactly one solution that does not involve backtracking
  23. (passing through a doorway more than once).
  24.  
  25.      This program was written by James L. Dean.
  26.  
  27. */
  28. #include <stdio.h>
  29. #include <string.h>
  30. #include <math.h>
  31. #include <stdlib.h>
  32. #include <conio.h>
  33. #include <dos.h>
  34. #include <graphics.h>
  35.  
  36. typedef struct corner_record
  37.           {
  38.             int x;
  39.             int y;
  40.           } corner_rec;
  41.  
  42. typedef struct vertex_record
  43.           {
  44.             double x;
  45.             double y;
  46.           } vertex_rec;
  47.  
  48. typedef struct triangle_record
  49.           {
  50.             vertex_rec vertex [3];
  51.           } triangle_rec;
  52.  
  53. typedef struct rectangle_record
  54.           {
  55.             vertex_rec vertex [4];
  56.           } rectangle_rec;
  57.  
  58. typedef struct stack_rec_record
  59.           {
  60.             char index_1;
  61.             int  index_2;
  62.           } stack_rec;
  63.  
  64. #define TRUE  1
  65. #define FALSE 0
  66.  
  67. #define GRAPHICS_DRIVER                VGA /* 640x480x16 VGA */
  68. #define GRAPHICS_MODE                VGAHI /* must support red, green, yellow,
  69.                                               and 9 shades of gray */
  70. #define NUM_COLORS                      16
  71. #define TOP_COLOR                       12 /* all but last 3 colors are gray */
  72. #define RECTANGLE_SE_NW_COLOR           10
  73. #define TRIANGLE_SSE_NNW_COLOR           9
  74. #define TRIANGLE_SE_NW_COLOR             8
  75. #define RECTANGLE_W_E_COLOR              7
  76. #define FLOOR_COLOR                      6
  77. #define TRIANGLE_SW_NE_COLOR             5 
  78. #define RECTANGLE_SW_NE_COLOR            4 
  79. #define TRIANGLE_SSW_NNE_COLOR           3
  80. #define BACKOUT_COLOR                   13
  81. #define ADVANCE_COLOR                   14
  82. #define SOLUTION_COLOR                  15
  83. #define WIDTH_OF_GRAPHICS_IN_INCHES      8.0
  84. #define NUM_X_PIXELS                   640
  85. #define WIDTH_OF_GRAPHICS_IN_PIXELS    640
  86. #define HEIGHT_OF_GRAPHICS_IN_INCHES     5.0
  87. #define NUM_Y_PIXELS                   480
  88. #define HEIGHT_OF_GRAPHICS_IN_PIXELS   400  
  89.  
  90. #define RELATIVE_WIDTH_OF_WALL           0.25 /* relative to side of hexagon */
  91. #define RELATIVE_HEIGHT_OF_WALL          2.0  /* relative to side of hexagon */
  92. #define MIN_WALL_LENGTH_IN_PIXELS       12
  93.  
  94. static void           display_quadrilateral(double,double,double,double,double,
  95.                        double,double,double,double,double,double,double,double,
  96.                        double,double,double,double,double,double,double,int);
  97. static void           display_solution(int,char **,double,double,double,double,
  98.                        double,double,double,double);
  99. static void           display_triangle(double,double,double,double,double,
  100.                        double,double,double,double,double,double,double,double,
  101.                        double,double,double,double,int);
  102. static void           draw_line(double,double,double,double,double,double,
  103.                        double,double,double,double,double,double);
  104. static void           free_memory(char ***,char ***,int,stack_rec **);
  105. static void           generate_maze(char **,int,int,stack_rec *,int,int,int *);
  106. static void           get_corner(double,double,double,double,double,double,
  107.                        double,double,double,double,double,corner_rec *);
  108. static void           get_cursor(unsigned char *,unsigned char *,
  109.                        unsigned char *,unsigned char *);
  110. static void           get_defaults(char *,int *,double *,char *,long *);
  111. static void           hash(int *,int *,int *,int *,int *,int *,int *,int *);
  112. static void           increment(int *,int *,int *,int *,int *,int *,int *,
  113.                        int *);
  114. static void           let_user_try_to_solve(int *,int,int,char **,char **,
  115.                        double,double,double,double,double,double,double,double);
  116.        int            main(int,char **);
  117. static int            memory_allocated(char ***,char ***,int,int,stack_rec **,
  118.                        int);
  119.        void interrupt new_critical_error_handler(void);
  120.        void interrupt (*old_critical_error_handler)(void);
  121. static void           output_maze(char **,int,int,double,double,double,double,
  122.                        double,double,double,double);
  123. static void           output_rectangle(double,double,double,rectangle_rec *,
  124.                        double,double,double,double,double,int);
  125. static void           output_triangle(double,double,double,triangle_rec *,
  126.                        double,double,double,double,double,int,int);
  127. static void           put_defaults(char *,int,double,char *,long);
  128. static void           select_maze(char *,char **,int,int,stack_rec *,int,int,
  129.                        int,long);
  130. static void           set_cursor_position(unsigned char,unsigned char);
  131. static void           set_cursor_size(unsigned char,unsigned char);
  132. static void           solve_maze(stack_rec *,char **,int *,int *,int,int);
  133. static void           titillate(void);
  134.  
  135. extern unsigned _stklen=0x8000;
  136.  
  137. static unsigned char cursor_column;
  138. static unsigned char cursor_row;
  139. static unsigned char cursor_start;
  140. static unsigned char cursor_stop;
  141. static int           delta_x [6] [720];
  142. static int           delta_y [6] [720];
  143. static int           file_opened;
  144. static double        sqrt_3;
  145. static char          titillator [4] = {'|','/','-','\\'};
  146. static int           titillator_index;
  147.  
  148. int main(
  149.   int  argc,
  150.   char *argv[])
  151.     {
  152.       register int                color_num;
  153.       static   char               **computer_page;
  154.       static   double             cos_tilt;
  155.       static   int                default_num_columns;
  156.       static   long               default_num_trials;
  157.       static   char               default_seed [256];
  158.       static   double             default_tilt;
  159.       static   int                delta_index_1a;
  160.       static   int                delta_index_1b;
  161.       static   int                delta_index_1c;
  162.       static   int                delta_index_1d;
  163.       static   int                delta_index_1e;
  164.       static   int                delta_index_1f;
  165.       static   int                delta_index_2;
  166.       static   int                ErrorCode;
  167.       static   int                fatal_error;
  168.       static   int                GraphDriver;
  169.       static   int                GraphMode;
  170.       static   char               line [256];
  171.       static   char               *line_ptr;
  172.       static   int                max_num_columns;
  173.       static   int                max_x;
  174.       static   int                max_x_plus_1;
  175.       static   int                max_y;
  176.       static   int                max_y_plus_1;
  177.       static   int                min_num_columns;
  178.       static   int                num_assigned;
  179.       static   int                num_columns;
  180.       static   int                num_rooms_in_maze;
  181.       static   int                num_rows;
  182.       static   long               num_trials; 
  183.       static   struct palettetype palette;
  184.       static   double             pixels_per_x;
  185.       static   double             pixels_per_z;
  186.       static   double             radians;
  187.       static   double             radians_per_degree;
  188.       static   double             rel_dist_of_user_from_screen;
  189.       static   int                response;
  190.       static   char               seed [256];
  191.       static   int                seed_index;
  192.       static   double             sin_tilt;
  193.       static   stack_rec          *stack;
  194.       static   double             tilt;
  195.       static   int                tint;
  196.       static   char               **user_page;
  197.       static   int                user_still_interested;
  198.       static   double             x_max;
  199.       static   double             x_offset;
  200.       static   double             y_max;
  201.  
  202.       fatal_error=FALSE;
  203.       delta_y[0][0]=-1;
  204.       delta_x[0][0]=-2;
  205.       delta_y[1][0]=1;
  206.       delta_x[1][0]=-2;
  207.       delta_y[2][0]=-2;
  208.       delta_x[2][0]=0;
  209.       delta_y[3][0]=2;
  210.       delta_x[3][0]=0;
  211.       delta_y[4][0]=-1;
  212.       delta_x[4][0]=2;
  213.       delta_y[5][0]=1;
  214.       delta_x[5][0]=2;
  215.       delta_index_2=0;
  216.       for (delta_index_1a=0; delta_index_1a < 6; delta_index_1a++)
  217.         for (delta_index_1b=0; delta_index_1b < 6; delta_index_1b++)
  218.           if (delta_index_1a != delta_index_1b)
  219.            for (delta_index_1c=0; delta_index_1c < 6; delta_index_1c++)
  220.              if ((delta_index_1a != delta_index_1c)
  221.              &&  (delta_index_1b != delta_index_1c))
  222.                for (delta_index_1d=0; delta_index_1d < 6; delta_index_1d++)
  223.                   if ((delta_index_1a != delta_index_1d)
  224.                   &&  (delta_index_1b != delta_index_1d)
  225.                   &&  (delta_index_1c != delta_index_1d))
  226.                     for (delta_index_1e=0; delta_index_1e < 6;
  227.                      delta_index_1e++)
  228.                       if ((delta_index_1a != delta_index_1e)
  229.                       &&  (delta_index_1b != delta_index_1e)
  230.                       &&  (delta_index_1c != delta_index_1e)
  231.                       &&  (delta_index_1d != delta_index_1e))
  232.                         for (delta_index_1f=0; delta_index_1f < 6;
  233.                          delta_index_1f++)
  234.                           if ((delta_index_1a != delta_index_1f)
  235.                           &&  (delta_index_1b != delta_index_1f)
  236.                           &&  (delta_index_1c != delta_index_1f)
  237.                           &&  (delta_index_1d != delta_index_1f)
  238.                           &&  (delta_index_1e != delta_index_1f))
  239.                             {
  240.                               delta_x[delta_index_1a][delta_index_2]
  241.                                =delta_x[0][0];
  242.                               delta_y[delta_index_1a][delta_index_2]
  243.                                =delta_y[0][0];
  244.                               delta_x[delta_index_1b][delta_index_2]
  245.                                =delta_x[1][0];
  246.                               delta_y[delta_index_1b][delta_index_2]
  247.                                =delta_y[1][0];
  248.                               delta_x[delta_index_1c][delta_index_2]
  249.                                =delta_x[2][0];
  250.                               delta_y[delta_index_1c][delta_index_2]
  251.                                =delta_y[2][0];
  252.                               delta_x[delta_index_1d][delta_index_2]
  253.                                =delta_x[3][0];
  254.                               delta_y[delta_index_1d][delta_index_2]
  255.                                =delta_y[3][0];
  256.                               delta_x[delta_index_1e][delta_index_2]
  257.                                =delta_x[4][0];
  258.                               delta_y[delta_index_1e][delta_index_2]
  259.                                =delta_y[4][0];
  260.                               delta_x[delta_index_1f][delta_index_2]
  261.                                =delta_x[5][0];
  262.                               delta_y[delta_index_1f][delta_index_2]
  263.                                =delta_y[5][0];
  264.                               delta_index_2++;
  265.                             };
  266.       sqrt_3=sqrt(3.0);
  267.       min_num_columns=3;
  268.       max_num_columns=(int) (2.0*(((double) WIDTH_OF_GRAPHICS_IN_PIXELS)
  269.        /((double) MIN_WALL_LENGTH_IN_PIXELS)-2.0
  270.        -((double) RELATIVE_WIDTH_OF_WALL)/sqrt_3)/3.0+1.0);
  271.       if (max_num_columns%2 == 0)
  272.         max_num_columns--;
  273.       if (max_num_columns < 3)
  274.         max_num_columns=3;
  275.       get_defaults(argv[0],&default_num_columns,&default_tilt,&default_seed[0],
  276.        &default_num_trials);
  277.       do
  278.         {
  279.           clrscr();
  280.           printf(
  281. "                              FMAZ41 -- Maze Game\n\n"
  282. "                             Version 4.1 (10/4/95)\n\n\n"
  283. "     Generate and solve mazes on your VGA (or better) display.\n\n"
  284. "     The mazes are displayed in three dimensions.\n\n"
  285. "     To get the value surrounded by [], just press Enter.\n\n");
  286.           do
  287.             {
  288.               printf("     Number of columns (%d to %d, or 0 to exit) [%d]?  ",
  289.                min_num_columns,max_num_columns,default_num_columns);
  290.               fflush(stdin);
  291.               fgets(&line[0],256,stdin);
  292.               line_ptr=&line[0];
  293.               while ((*line_ptr == ' ') || (*line_ptr == (char) 9))
  294.                 line_ptr++;
  295.               if ((*line_ptr == '\n') || (*line_ptr == '\0'))
  296.                 num_columns=default_num_columns;
  297.               else
  298.                 {
  299.                   num_assigned=sscanf(line_ptr,"%d",&num_columns);
  300.                   if ((num_assigned == 0) || (num_assigned == EOF))
  301.                     num_columns=-1;
  302.                 }
  303.             }
  304.           while ((num_columns != 0)
  305.           &&     ((num_columns < min_num_columns) 
  306.                || (num_columns > max_num_columns)));
  307.           user_still_interested=num_columns;
  308.           if (user_still_interested)
  309.             {
  310.               printf("\n");
  311.               if (num_columns%2 == 0)
  312.                 num_columns++;
  313.               num_rows=(int) (((((double) HEIGHT_OF_GRAPHICS_IN_INCHES)
  314.                /((double) WIDTH_OF_GRAPHICS_IN_INCHES))
  315.                *(3.0*(((double) num_columns)-1.0)/2.0+2.0
  316.                +((double) RELATIVE_WIDTH_OF_WALL)/sqrt_3)
  317.                -((double) RELATIVE_WIDTH_OF_WALL))/sqrt_3);
  318.               if (num_rows < 2)
  319.                 num_rows=2;
  320.               do
  321.                 {
  322.                   printf("     Tilt (30 to 60 degrees) [%lf]?  ",default_tilt);
  323.                   fflush(stdin);
  324.                   fgets(&line[0],256,stdin);
  325.                   line_ptr=&line[0];
  326.                   while ((*line_ptr == ' ') || (*line_ptr == (char) 9))
  327.                     line_ptr++;
  328.                   if ((*line_ptr == '\n') || (*line_ptr == '\0'))
  329.                     tilt=default_tilt;
  330.                   else
  331.                     {
  332.                       num_assigned=sscanf(line_ptr,"%lf",&tilt);
  333.                       if ((num_assigned == 0) || (num_assigned == EOF))
  334.                         tilt=(double) 0.0;
  335.                     }
  336.                 }
  337.               while ((tilt < (double) 30.0) || (tilt > (double) 60.0));
  338.               printf("\n");
  339.               do
  340.                 {
  341.                   printf("     Number of trials to allow for maze selection "
  342.                    "[%ld]?  ",default_num_trials);
  343.                   fflush(stdin);
  344.                   fgets(&line[0],256,stdin);
  345.                   line_ptr=&line[0];
  346.                   while ((*line_ptr == ' ') || (*line_ptr == (char) 9))
  347.                     line_ptr++;
  348.                   if ((*line_ptr == '\n') || (*line_ptr == '\0'))
  349.                     num_trials=default_num_trials;
  350.                   else
  351.                     {
  352.                       num_assigned=sscanf(line_ptr,"%ld",&num_trials);
  353.                       if ((num_assigned == 0) || (num_assigned == EOF))
  354.                         num_trials=0L;
  355.                     }
  356.                 }
  357.               while (num_trials <= 0L);
  358.               printf("\n     Random number seed (8 or fewer digits) [%s]?  ",
  359.                &default_seed[0]);
  360.               fflush(stdin);
  361.               fgets(&line[0],256,stdin);
  362.               line_ptr=&line[0];
  363.               while ((*line_ptr == ' ') || (*line_ptr == (char) 9))
  364.                 line_ptr++;
  365.               if ((*line_ptr != '\n') && (*line_ptr != '\0'))
  366.                 {
  367.                   seed_index=0;
  368.                   while ((seed_index < 8) 
  369.                   &&     (*line_ptr)
  370.                   &&     (*line_ptr != '\n'))
  371.                     default_seed[seed_index++]=*(line_ptr++);
  372.                   default_seed[seed_index]='\0';
  373.                 }
  374.               strcpy(&seed[0],&default_seed[0]);
  375.               default_num_columns=num_columns;
  376.               default_tilt=tilt;
  377.               default_num_trials=num_trials;
  378.               max_x=8*(num_columns/2)+6;
  379.               max_x_plus_1=max_x+1;
  380.               max_y=4*num_rows;
  381.               max_y_plus_1=max_y+1;
  382.               num_rooms_in_maze=num_rows*num_columns-(num_columns/2);
  383.               if (memory_allocated(&computer_page,&user_page,max_x_plus_1,
  384.                max_y_plus_1,&stack,num_rooms_in_maze))
  385.                 {
  386.                   printf(
  387. "\n     While the maze is being selected, a spinning cursor is displayed:  ");
  388.                   select_maze(&seed[0],computer_page,max_x,max_y,stack,
  389.                    num_rooms_in_maze,num_columns,num_rows,num_trials);
  390.                   registerbgidriver(EGAVGA_driver);
  391.                   /*
  392.                      See the Borland documentation on the
  393.                      utilities "BINOBJ" and "TLIB" for 
  394.                      information on how to link "EGAVGA.BGI"
  395.                      into a program from "GRAPHICS.LIB".
  396.                   */
  397.                   GraphDriver=GRAPHICS_DRIVER;
  398.                   GraphMode=GRAPHICS_MODE;
  399.                   initgraph(&GraphDriver,&GraphMode,"");
  400.                   ErrorCode=graphresult();
  401.                   if (ErrorCode == 0)
  402.                     {
  403.                       getpalette(&palette);
  404.                       for (color_num=0; 
  405.                        color_num < (NUM_COLORS-3);
  406.                        color_num++)
  407.                         { /* evenly spaced shades of gray */
  408.                           tint=(63*color_num)/(NUM_COLORS-3);
  409.                           tint&=0xfc;
  410.                           setrgbpalette(
  411.                            palette.colors[color_num],
  412.                            tint,tint,tint);
  413.                         }
  414.                       setrgbpalette(
  415.                        palette.colors[BACKOUT_COLOR],
  416.                        0xfc,0xfc,0);
  417.                       setrgbpalette(
  418.                        palette.colors[ADVANCE_COLOR],
  419.                        0,0xfc,0);
  420.                       setrgbpalette(
  421.                        palette.colors[SOLUTION_COLOR],
  422.                        0xfc,0,0);
  423.                       settextjustify(CENTER_TEXT,BOTTOM_TEXT);
  424.                       settextstyle(DEFAULT_FONT,HORIZ_DIR,0);
  425.                       setcolor(NUM_COLORS-4);
  426.                       outtextxy(NUM_X_PIXELS/2,NUM_Y_PIXELS-1,
  427.                 "Home PgUp PgDn End \030 \031 - Move    S - Solve    Q - Quit");
  428.                       radians_per_degree=atan(1.0)/45.0;
  429.                       radians=tilt*radians_per_degree;
  430.                       sin_tilt=sin(radians);
  431.                       cos_tilt=cos(radians);
  432.                       x_max=3.0*(((double) num_columns)-1.0)/2.0+2.0
  433.                        +RELATIVE_WIDTH_OF_WALL/sqrt_3;
  434.                       pixels_per_x
  435.                        =(((double) WIDTH_OF_GRAPHICS_IN_PIXELS)-1.0)
  436.                        /(x_max*(x_max/(x_max-RELATIVE_HEIGHT_OF_WALL)));
  437.                       x_offset=(x_max/2.0)*(RELATIVE_HEIGHT_OF_WALL
  438.                        /(x_max-RELATIVE_HEIGHT_OF_WALL));
  439.                       y_max
  440.                        =((double) num_rows)*sqrt_3+RELATIVE_WIDTH_OF_WALL;
  441.                       pixels_per_z
  442.                        =(((double) HEIGHT_OF_GRAPHICS_IN_PIXELS)-1.0)
  443.                        /sqrt(y_max*y_max
  444.                        +RELATIVE_HEIGHT_OF_WALL*RELATIVE_HEIGHT_OF_WALL);
  445.                       if (y_max > x_max)
  446.                         rel_dist_of_user_from_screen=y_max;
  447.                       else
  448.                         rel_dist_of_user_from_screen=x_max;
  449.                       output_maze(computer_page,max_x,max_y,x_max,x_offset,
  450.                        y_max,cos_tilt,sin_tilt,pixels_per_x,pixels_per_z,
  451.                        rel_dist_of_user_from_screen);
  452.                       let_user_try_to_solve(&response,max_x,max_y,computer_page,
  453.                        user_page,x_max,x_offset,y_max,cos_tilt,sin_tilt,
  454.                        pixels_per_x,pixels_per_z,rel_dist_of_user_from_screen);
  455.                       if ((response == (int) 's')
  456.                       ||  (response == (int) 'S'))
  457.                         {
  458.                           display_solution(max_y,computer_page,x_max,x_offset,
  459.                            y_max,cos_tilt,sin_tilt,pixels_per_x,pixels_per_z,
  460.                            rel_dist_of_user_from_screen);
  461.                           setcolor(NUM_COLORS-4);
  462.                           outtextxy(NUM_X_PIXELS/2,
  463.                            NUM_Y_PIXELS-1,
  464.                            "Press a key to continue.");
  465.                           response=getch();
  466.                           if (response == 0)
  467.                             response=getch();
  468.                         }
  469.                       closegraph();
  470.                     }
  471.                   else
  472.                     {
  473.                       printf("     Fatal error:  %s\n",
  474.                        grapherrormsg(ErrorCode));
  475.                       fatal_error=TRUE;
  476.                     }
  477.                   free_memory(&computer_page,&user_page,max_y_plus_1,&stack);
  478.                 }
  479.               else
  480.                 {
  481.                   fatal_error=TRUE;
  482.                   printf("     Fatal error:  out of memory.\n");
  483.                 }
  484.             }
  485.         }
  486.       while ((! fatal_error) && (user_still_interested));
  487.       if (! fatal_error)
  488.         put_defaults(argv[0],default_num_columns,default_tilt,
  489.          &default_seed[0],default_num_trials);
  490.       return fatal_error;
  491.     }
  492.  
  493. static void get_defaults(
  494.   char   *argv,
  495.   int    *default_num_columns,
  496.   double *default_tilt,
  497.   char   *default_seed,
  498.   long   *default_num_trials)
  499.     {
  500.       register int  arg_index;
  501.       static   char *arg_ptr;
  502.                FILE *defaults;
  503.       static   char file_name [256];
  504.       static   int  last_period_index;
  505.       static   char line [256];
  506.       static   char *line_ptr;
  507.       static   int  num_assigned;
  508.       static   int  seed_length;
  509.       static   char *seed_ptr;
  510.  
  511.       arg_index=0;
  512.       arg_ptr=argv;
  513.       last_period_index=-1;
  514.       while ((*arg_ptr) && (arg_index < 252))
  515.         {
  516.           if (*arg_ptr == '.')
  517.             last_period_index=arg_index;
  518.           file_name[arg_index++]=*(arg_ptr++);
  519.         }
  520.       if ((*arg_ptr) || (last_period_index < 0))
  521.         {
  522.           *default_num_columns=17;
  523.           *default_tilt=(double) 30.0;
  524.           default_seed[0]='1';
  525.           default_seed[1]='\0';
  526.         }
  527.       else
  528.         {
  529.           file_name[++last_period_index]='I';
  530.           file_name[++last_period_index]='N';
  531.           file_name[++last_period_index]='I';
  532.           file_name[++last_period_index]='\0';
  533.           if ((defaults=fopen(&file_name[0],"r")) == NULL)
  534.             {
  535.               *default_num_columns=17;
  536.               *default_tilt=(double) 30.0;
  537.               default_seed[0]='1';
  538.               default_seed[1]='\0';
  539.               *default_num_trials=5L;
  540.             }
  541.           else
  542.             {
  543.               line_ptr=fgets(&line[0],256,defaults);
  544.               if (line_ptr == NULL)
  545.                 {
  546.                   *default_num_columns=17;
  547.                   *default_tilt=(double) 30.0;
  548.                   default_seed[0]='1';
  549.                   default_seed[1]='\0';
  550.                   *default_num_trials=5L;
  551.                 }
  552.               else
  553.                 {
  554.                   while ((*line_ptr == ' ') || (*line_ptr == (char) 9))
  555.                     line_ptr++;
  556.                   if ((*line_ptr == '\n') || (*line_ptr == '\0'))
  557.                     *default_num_columns=17;
  558.                   else
  559.                     {
  560.                       num_assigned=sscanf(line_ptr,"%d",default_num_columns);
  561.                       if ((num_assigned == 0) || (num_assigned == EOF))
  562.                         *default_num_columns=17;
  563.                     }
  564.                   line_ptr=fgets(&line[0],256,defaults);
  565.                   if (line_ptr == NULL)
  566.                     {
  567.                       *default_tilt=(double) 30.0;
  568.                       default_seed[0]='1';
  569.                       default_seed[1]='\0';
  570.                       *default_num_trials=5L;
  571.                     }
  572.                   else
  573.                     {
  574.                       while ((*line_ptr == ' ') || (*line_ptr == (char) 9))
  575.                         line_ptr++;
  576.                       if ((*line_ptr == '\n') || (*line_ptr == '\0'))
  577.                         *default_tilt=(double) 30.0;
  578.                       else
  579.                         {
  580.                           num_assigned=sscanf(line_ptr,"%lf",default_tilt);
  581.                           if ((num_assigned == 0) || (num_assigned == EOF))
  582.                             *default_tilt=(double) 30.0;
  583.                         }
  584.                       line_ptr=fgets(&line[0],256,defaults);
  585.                       if (line_ptr == NULL)
  586.                         {
  587.                           default_seed[0]='1';
  588.                           default_seed[1]='\0';
  589.                           *default_num_trials=5L;
  590.                         }
  591.                       else
  592.                         {
  593.                           while ((*line_ptr == ' ') || (*line_ptr == (char) 9))
  594.                             line_ptr++;
  595.                           seed_ptr=default_seed;
  596.                           if ((*line_ptr == '\n') || (*line_ptr == '\0'))
  597.                             *(seed_ptr++)='1';
  598.                           else
  599.                             {
  600.                               seed_length=0;
  601.                               while ((seed_length < 8)
  602.                               &&     (*line_ptr)
  603.                               &&     (*line_ptr != '\n')) 
  604.                                 {
  605.                                   *(seed_ptr++)=*(line_ptr++);
  606.                                   seed_length++;
  607.                                 }
  608.                             }
  609.                           *seed_ptr='\0';
  610.                           line_ptr=fgets(&line[0],256,defaults);
  611.                           if (line_ptr == NULL)
  612.                             *default_num_trials=5L;
  613.                           else
  614.                             {
  615.                               while ((*line_ptr == ' ')
  616.                               ||     (*line_ptr == (char) 9))
  617.                                 line_ptr++;
  618.                               if ((*line_ptr == '\n') || (*line_ptr == '\0'))
  619.                                 *default_num_trials=5L;
  620.                               else
  621.                                 {
  622.                                   num_assigned
  623.                                    =sscanf(line_ptr,"%ld",default_num_trials);
  624.                                   if ((num_assigned == 0) 
  625.                                   ||  (num_assigned == EOF))
  626.                                     *default_num_trials=5L;
  627.                                 }
  628.                             }
  629.                         }
  630.                     }
  631.                 }
  632.               fclose(defaults);
  633.             }
  634.         }
  635.       return;
  636.     }
  637.  
  638. void interrupt new_critical_error_handler()
  639.     {
  640.       file_opened=FALSE;
  641.       return;
  642.     }
  643.  
  644. static void put_defaults(
  645.   char   *argv,
  646.   int    num_columns,
  647.   double tilt,
  648.   char   *seed,
  649.   long   num_trials)
  650.     {
  651.       static int  arg_index;
  652.       static char *arg_ptr;
  653.              FILE *defaults;
  654.       static char file_name [256];
  655.       static int  last_period_index;
  656.  
  657.       arg_index=0;
  658.       arg_ptr=argv;
  659.       last_period_index=-1;
  660.       while ((*arg_ptr) && (arg_index < 252))
  661.         {
  662.           if (*arg_ptr == '.')
  663.             last_period_index=arg_index;
  664.           file_name[arg_index++]=*(arg_ptr++);
  665.         }
  666.       if ((*arg_ptr == '\0') && (last_period_index >= 0))
  667.         {
  668.           file_name[++last_period_index]='I';
  669.           file_name[++last_period_index]='N';
  670.           file_name[++last_period_index]='I';
  671.           file_name[++last_period_index]='\0';
  672.           old_critical_error_handler=getvect(0x24);
  673.           setvect(0x24,new_critical_error_handler);
  674.           file_opened=TRUE;
  675.           if ((defaults=fopen(&file_name[0],"w")) != NULL)
  676.             {
  677.               setvect(0x24,old_critical_error_handler);
  678.               if (file_opened)
  679.                 {
  680.                   fprintf(defaults,"%d\n%lf\n%s\n%ld\n",num_columns,tilt,seed,
  681.                    num_trials);
  682.                   fclose(defaults);
  683.                 }
  684.             }
  685.           else 
  686.             setvect(0x24,old_critical_error_handler);           
  687.         }
  688.       return;
  689.     }
  690.  
  691. static void get_corner(
  692.   double     x,
  693.   double     y,
  694.   double     z,
  695.   double     pixels_per_x,
  696.   double     pixels_per_z,
  697.   double     cos_tilt,
  698.   double     sin_tilt,
  699.   double     rel_dist_of_user_from_screen,
  700.   double     x_max,
  701.   double     x_offset,
  702.   double     y_max,
  703.   corner_rec *corner)
  704.     {
  705.       double x_adjusted;
  706.       double y_prime;
  707.       double z_adjusted;
  708.       double z_prime;
  709.       
  710.       y_prime=(y_max-y)*cos_tilt-z*sin_tilt;
  711.       z_prime=(y_max-y)*sin_tilt+z*cos_tilt;
  712.       z_adjusted=(y_max/2.0)+rel_dist_of_user_from_screen
  713.        *(z_prime-(y_max/2.0))/(y_prime+rel_dist_of_user_from_screen);
  714.       x_adjusted=(x_max/2.0)+rel_dist_of_user_from_screen
  715.        *(x-(x_max/2.0))/(y_prime+rel_dist_of_user_from_screen);
  716.       x_adjusted+=x_offset;
  717.       corner->x=(int) (pixels_per_x*x_adjusted);
  718.       corner->y
  719.        =(HEIGHT_OF_GRAPHICS_IN_PIXELS-1)-((int) (pixels_per_z*z_adjusted));
  720.       return;
  721.     }
  722.  
  723. static void display_quadrilateral(
  724.   double x_max,
  725.   double x_offset,
  726.   double y_max,
  727.   double x0,
  728.   double y0,
  729.   double z0,
  730.   double x1,
  731.   double y1,
  732.   double z1,
  733.   double x2,
  734.   double y2,
  735.   double z2,
  736.   double x3,
  737.   double y3,
  738.   double z3,
  739.   double pixels_per_x,
  740.   double pixels_per_z,
  741.   double cos_tilt,
  742.   double sin_tilt,
  743.   double rel_dist_of_user_from_screen,
  744.   int    color)
  745.     {
  746.       static corner_rec quadrilateral [4];
  747.  
  748.       get_corner(x0,y0,z0,pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  749.        rel_dist_of_user_from_screen,x_max,x_offset,y_max,&quadrilateral[0]);
  750.       get_corner(x1,y1,z1,pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  751.        rel_dist_of_user_from_screen,x_max,x_offset,y_max,&quadrilateral[1]);
  752.       get_corner(x2,y2,z2,pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  753.        rel_dist_of_user_from_screen,x_max,x_offset,y_max,&quadrilateral[2]);
  754.       get_corner(x3,y3,z3,pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  755.        rel_dist_of_user_from_screen,x_max,x_offset,y_max,&quadrilateral[3]);
  756.       setcolor(color);
  757.       setfillstyle(SOLID_FILL,color);
  758.       fillpoly(4,&(quadrilateral[0].x));
  759.       return;
  760.     }
  761.  
  762. static void display_triangle(
  763.   double x_max,
  764.   double x_offset,
  765.   double y_max,
  766.   double x0,
  767.   double y0,
  768.   double z0,
  769.   double x1,
  770.   double y1,
  771.   double z1,
  772.   double x2,
  773.   double y2,
  774.   double z2,
  775.   double pixels_per_x,
  776.   double pixels_per_z,
  777.   double cos_tilt,
  778.   double sin_tilt,
  779.   double rel_dist_of_user_from_screen,
  780.   int    color)
  781.     {
  782.       static corner_rec triangle [3];
  783.  
  784.       get_corner(x0,y0,z0,pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  785.        rel_dist_of_user_from_screen,x_max,x_offset,y_max,&triangle[0]);
  786.       get_corner(x1,y1,z1,pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  787.        rel_dist_of_user_from_screen,x_max,x_offset,y_max,&triangle[1]);
  788.       get_corner(x2,y2,z2,pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  789.        rel_dist_of_user_from_screen,x_max,x_offset,y_max,&triangle[2]);
  790.       setcolor(color);
  791.       setfillstyle(SOLID_FILL,color);
  792.       fillpoly(3,&(triangle[0].x));
  793.       return;
  794.     }
  795.  
  796. static void output_triangle(
  797.   double       x_max,
  798.   double       x_offset,
  799.   double       y_max,
  800.   triangle_rec *triangle,
  801.   double       pixels_per_x,
  802.   double       pixels_per_z,
  803.   double       cos_tilt,
  804.   double       sin_tilt,
  805.   double       rel_dist_of_user_from_screen,
  806.   int          first_pass,
  807.   int          face_color)
  808.     {
  809.       if (first_pass)
  810.         {
  811.           if (((*triangle).vertex[1].x < x_max/2.0)
  812.           &&  ((*triangle).vertex[1].x > (*triangle).vertex[0].x))
  813.             display_quadrilateral(x_max,x_offset,y_max,
  814.              (*triangle).vertex[2].x,(*triangle).vertex[2].y,
  815.              RELATIVE_HEIGHT_OF_WALL,
  816.              (*triangle).vertex[1].x,(*triangle).vertex[1].y,
  817.              RELATIVE_HEIGHT_OF_WALL,
  818.              (*triangle).vertex[1].x,(*triangle).vertex[1].y,0.0,
  819.              (*triangle).vertex[2].x,(*triangle).vertex[2].y,0.0,
  820.              pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  821.              rel_dist_of_user_from_screen,TRIANGLE_SSW_NNE_COLOR);
  822.           if (((*triangle).vertex[1].x > x_max/2.0)
  823.           &&  ((*triangle).vertex[1].x < (*triangle).vertex[2].x))
  824.             display_quadrilateral(x_max,x_offset,y_max,
  825.              (*triangle).vertex[1].x,(*triangle).vertex[1].y,
  826.              RELATIVE_HEIGHT_OF_WALL,
  827.              (*triangle).vertex[0].x,(*triangle).vertex[0].y,
  828.              RELATIVE_HEIGHT_OF_WALL,
  829.              (*triangle).vertex[0].x,(*triangle).vertex[0].y,0.0,
  830.              (*triangle).vertex[1].x,(*triangle).vertex[1].y,0.0,
  831.              pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  832.              rel_dist_of_user_from_screen,TRIANGLE_SSE_NNW_COLOR);
  833.         }
  834.       else
  835.         {
  836.           display_quadrilateral(x_max,x_offset,y_max,
  837.            (*triangle).vertex[0].x,(*triangle).vertex[0].y,
  838.            RELATIVE_HEIGHT_OF_WALL,
  839.            (*triangle).vertex[2].x,(*triangle).vertex[2].y,
  840.            RELATIVE_HEIGHT_OF_WALL,
  841.            (*triangle).vertex[2].x,(*triangle).vertex[2].y,0.0,
  842.            (*triangle).vertex[0].x,(*triangle).vertex[0].y,0.0,
  843.            pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  844.            rel_dist_of_user_from_screen,face_color);
  845.           display_triangle(x_max,x_offset,y_max,
  846.            (*triangle).vertex[0].x,(*triangle).vertex[0].y,
  847.            RELATIVE_HEIGHT_OF_WALL,
  848.            (*triangle).vertex[1].x,(*triangle).vertex[1].y,
  849.            RELATIVE_HEIGHT_OF_WALL,
  850.            (*triangle).vertex[2].x,(*triangle).vertex[2].y,
  851.            RELATIVE_HEIGHT_OF_WALL,
  852.            pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  853.            rel_dist_of_user_from_screen,TOP_COLOR);
  854.         }
  855.       return;
  856.     }
  857.  
  858. static void output_rectangle(
  859.   double        x_max,
  860.   double        x_offset,
  861.   double        y_max,
  862.   rectangle_rec *rectangle,
  863.   double        pixels_per_x,
  864.   double        pixels_per_z,
  865.   double        cos_tilt,
  866.   double        sin_tilt,
  867.   double        rel_dist_of_user_from_screen,
  868.   int           face_color)
  869.     {
  870.       display_quadrilateral(x_max,x_offset,y_max,
  871.        (*rectangle).vertex[3].x,(*rectangle).vertex[3].y,
  872.        RELATIVE_HEIGHT_OF_WALL,
  873.        (*rectangle).vertex[2].x,(*rectangle).vertex[2].y,
  874.        RELATIVE_HEIGHT_OF_WALL,
  875.        (*rectangle).vertex[2].x,(*rectangle).vertex[2].y,0.0,
  876.        (*rectangle).vertex[3].x,(*rectangle).vertex[3].y,0.0,
  877.        pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  878.        rel_dist_of_user_from_screen,face_color);
  879.       display_quadrilateral(x_max,x_offset,y_max,
  880.        (*rectangle).vertex[0].x,(*rectangle).vertex[0].y,
  881.        RELATIVE_HEIGHT_OF_WALL,
  882.        (*rectangle).vertex[1].x,(*rectangle).vertex[1].y,
  883.        RELATIVE_HEIGHT_OF_WALL,
  884.        (*rectangle).vertex[2].x,(*rectangle).vertex[2].y,
  885.        RELATIVE_HEIGHT_OF_WALL,
  886.        (*rectangle).vertex[3].x,(*rectangle).vertex[3].y,
  887.        RELATIVE_HEIGHT_OF_WALL,
  888.        pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  889.        rel_dist_of_user_from_screen,TOP_COLOR);
  890.       return;
  891.     }
  892.  
  893. static void output_maze(
  894.   char   **page,
  895.   int    max_x,
  896.   int    max_y,
  897.   double x_max,
  898.   double x_offset,
  899.   double y_max,
  900.   double cos_tilt,
  901.   double sin_tilt,
  902.   double pixels_per_x,
  903.   double pixels_per_z,
  904.   double rel_dist_of_user_from_screen)
  905.     {
  906.       static   rectangle_rec base_rectangle [6];
  907.       static   triangle_rec  base_triangle [4];
  908.       static   int           object_num;
  909.       static   rectangle_rec rectangle [6];
  910.       static   triangle_rec  triangle [4];
  911.       static   int           vertex_num;
  912.       register int           x;
  913.       static   int           x_mod_8;
  914.       register int           y;
  915.       static   int           y_mod_4;
  916.       static   double        y_offset;
  917.  
  918.       base_triangle[0].vertex[0].x=0.0;
  919.       base_triangle[0].vertex[0].y=RELATIVE_WIDTH_OF_WALL+sqrt_3/2.0;
  920.       base_triangle[0].vertex[1].x=0.0;
  921.       base_triangle[0].vertex[1].y=sqrt_3/2.0;
  922.       base_triangle[0].vertex[2].x=RELATIVE_WIDTH_OF_WALL*sqrt_3/2.0;
  923.       base_triangle[0].vertex[2].y=(RELATIVE_WIDTH_OF_WALL+sqrt_3)/2.0;
  924.       base_triangle[1].vertex[0].x=(1.0-RELATIVE_WIDTH_OF_WALL/sqrt_3)/2.0;
  925.       base_triangle[1].vertex[0].y=RELATIVE_WIDTH_OF_WALL/2.0;
  926.       base_triangle[1].vertex[1].x=0.5+RELATIVE_WIDTH_OF_WALL/sqrt_3;
  927.       base_triangle[1].vertex[1].y=0.0;
  928.       base_triangle[1].vertex[2].x=base_triangle[1].vertex[1].x;
  929.       base_triangle[1].vertex[2].y=RELATIVE_WIDTH_OF_WALL;
  930.       base_triangle[2].vertex[0].x=1.5;
  931.       base_triangle[2].vertex[0].y=RELATIVE_WIDTH_OF_WALL;
  932.       base_triangle[2].vertex[1].x=1.5;
  933.       base_triangle[2].vertex[1].y=0.0;
  934.       base_triangle[2].vertex[2].x=1.5*(1.0+RELATIVE_WIDTH_OF_WALL/sqrt_3);
  935.       base_triangle[2].vertex[2].y=RELATIVE_WIDTH_OF_WALL/2.0;
  936.       base_triangle[3].vertex[0].x=2.0-RELATIVE_WIDTH_OF_WALL/(2.0*sqrt_3);
  937.       base_triangle[3].vertex[0].y=base_triangle[0].vertex[2].y;
  938.       base_triangle[3].vertex[1].x=2.0+RELATIVE_WIDTH_OF_WALL/sqrt_3;
  939.       base_triangle[3].vertex[1].y=base_triangle[0].vertex[1].y;
  940.       base_triangle[3].vertex[2].x=base_triangle[3].vertex[1].x;
  941.       base_triangle[3].vertex[2].y=base_triangle[0].vertex[0].y;
  942.       base_rectangle[0].vertex[0].x=base_triangle[0].vertex[2].x;
  943.       base_rectangle[0].vertex[0].y=base_triangle[0].vertex[2].y;
  944.       base_rectangle[0].vertex[1].x=base_triangle[1].vertex[1].x;
  945.       base_rectangle[0].vertex[1].y=sqrt_3;
  946.       base_rectangle[0].vertex[2].x=base_triangle[1].vertex[0].x;
  947.       base_rectangle[0].vertex[2].y=sqrt_3+RELATIVE_WIDTH_OF_WALL/2.0;
  948.       base_rectangle[0].vertex[3].x=base_triangle[0].vertex[0].x;
  949.       base_rectangle[0].vertex[3].y=base_triangle[0].vertex[0].y;
  950.       base_rectangle[1].vertex[0].x=base_triangle[0].vertex[1].x;
  951.       base_rectangle[1].vertex[0].y=base_triangle[0].vertex[1].y;
  952.       base_rectangle[1].vertex[1].x=base_triangle[1].vertex[0].x;
  953.       base_rectangle[1].vertex[1].y=base_triangle[1].vertex[0].y;
  954.       base_rectangle[1].vertex[2].x=base_triangle[1].vertex[2].x;
  955.       base_rectangle[1].vertex[2].y=base_triangle[1].vertex[2].y;
  956.       base_rectangle[1].vertex[3].x=base_triangle[0].vertex[2].x;
  957.       base_rectangle[1].vertex[3].y=base_triangle[0].vertex[2].y;         
  958.       base_rectangle[2].vertex[0].x=base_triangle[1].vertex[1].x;
  959.       base_rectangle[2].vertex[0].y=base_triangle[1].vertex[1].y;
  960.       base_rectangle[2].vertex[1].x=base_triangle[2].vertex[1].x;
  961.       base_rectangle[2].vertex[1].y=base_triangle[2].vertex[1].y;
  962.       base_rectangle[2].vertex[2].x=base_triangle[2].vertex[0].x;
  963.       base_rectangle[2].vertex[2].y=base_triangle[2].vertex[0].y;
  964.       base_rectangle[2].vertex[3].x=base_triangle[1].vertex[2].x;
  965.       base_rectangle[2].vertex[3].y=base_triangle[1].vertex[2].y;         
  966.       base_rectangle[3].vertex[0].x=base_triangle[2].vertex[2].x;
  967.       base_rectangle[3].vertex[0].y=base_triangle[2].vertex[2].y;
  968.       base_rectangle[3].vertex[1].x=base_triangle[3].vertex[1].x;
  969.       base_rectangle[3].vertex[1].y=base_triangle[3].vertex[1].y;
  970.       base_rectangle[3].vertex[2].x=base_triangle[3].vertex[0].x;
  971.       base_rectangle[3].vertex[2].y=base_triangle[3].vertex[0].y;
  972.       base_rectangle[3].vertex[3].x=base_triangle[2].vertex[0].x;
  973.       base_rectangle[3].vertex[3].y=base_triangle[2].vertex[0].y;         
  974.       base_rectangle[4].vertex[0].x=base_triangle[3].vertex[1].x;
  975.       base_rectangle[4].vertex[0].y=base_triangle[3].vertex[1].y;
  976.       base_rectangle[4].vertex[1].x=base_triangle[3].vertex[1].x
  977.        +(base_triangle[2].vertex[1].x-base_triangle[1].vertex[1].x);
  978.       base_rectangle[4].vertex[1].y=base_triangle[3].vertex[1].y;
  979.       base_rectangle[4].vertex[2].x=base_rectangle[4].vertex[1].x;
  980.       base_rectangle[4].vertex[2].y=base_triangle[3].vertex[2].y;
  981.       base_rectangle[4].vertex[3].x=base_triangle[3].vertex[2].x;
  982.       base_rectangle[4].vertex[3].y=base_triangle[3].vertex[2].y;         
  983.       base_rectangle[5].vertex[0].x=base_rectangle[0].vertex[1].x
  984.        +(base_triangle[2].vertex[1].x-base_triangle[1].vertex[1].x);
  985.       base_rectangle[5].vertex[0].y=base_rectangle[0].vertex[1].y;
  986.       base_rectangle[5].vertex[1].x=base_triangle[3].vertex[0].x;
  987.       base_rectangle[5].vertex[1].y=base_triangle[3].vertex[0].y;
  988.       base_rectangle[5].vertex[2].x=base_triangle[3].vertex[2].x;
  989.       base_rectangle[5].vertex[2].y=base_triangle[3].vertex[2].y;
  990.       base_rectangle[5].vertex[3].x=base_rectangle[0].vertex[2].x
  991.        +(base_triangle[2].vertex[2].x-base_triangle[1].vertex[0].x);
  992.       base_rectangle[5].vertex[3].y=base_rectangle[0].vertex[2].y;
  993.       rectangle[0].vertex[0].x=base_triangle[1].vertex[1].x;
  994.       rectangle[0].vertex[0].y=base_triangle[1].vertex[1].y;
  995.       rectangle[0].vertex[1].x=x_max-base_triangle[1].vertex[1].x;
  996.       rectangle[0].vertex[1].y=base_triangle[1].vertex[1].y;
  997.       rectangle[0].vertex[2].x=x_max-base_triangle[1].vertex[2].x;
  998.       rectangle[0].vertex[2].y=base_triangle[1].vertex[2].y;
  999.       rectangle[0].vertex[3].x=base_triangle[1].vertex[2].x;
  1000.       rectangle[0].vertex[3].y=base_triangle[1].vertex[2].y;
  1001.       rectangle[1].vertex[0].x=base_triangle[0].vertex[1].x;
  1002.       rectangle[1].vertex[0].y=base_triangle[0].vertex[1].y;
  1003.       rectangle[1].vertex[1].x=x_max-base_triangle[0].vertex[1].x;
  1004.       rectangle[1].vertex[1].y=base_triangle[0].vertex[1].y;
  1005.       rectangle[1].vertex[2].x=x_max-base_triangle[1].vertex[2].x;
  1006.       rectangle[1].vertex[2].y=base_triangle[1].vertex[2].y;
  1007.       rectangle[1].vertex[3].x=base_triangle[1].vertex[2].x;
  1008.       rectangle[1].vertex[3].y=base_triangle[1].vertex[2].y;
  1009.       rectangle[2].vertex[0].x=base_triangle[0].vertex[1].x;
  1010.       rectangle[2].vertex[0].y=base_triangle[0].vertex[1].y;
  1011.       rectangle[2].vertex[1].x=x_max-base_triangle[0].vertex[1].x;
  1012.       rectangle[2].vertex[1].y=base_triangle[0].vertex[1].y;
  1013.       rectangle[2].vertex[2].x=x_max-base_triangle[0].vertex[0].x;
  1014.       rectangle[2].vertex[2].y=base_triangle[0].vertex[0].y;
  1015.       rectangle[2].vertex[3].x=base_triangle[0].vertex[0].x;
  1016.       rectangle[2].vertex[3].y=base_triangle[0].vertex[0].y;
  1017.       rectangle[3].vertex[0].x=base_triangle[0].vertex[0].x;
  1018.       rectangle[3].vertex[0].y=base_triangle[0].vertex[0].y;
  1019.       rectangle[3].vertex[1].x=x_max-base_triangle[0].vertex[0].x;
  1020.       rectangle[3].vertex[1].y=base_triangle[0].vertex[0].y;
  1021.       rectangle[3].vertex[2].x=x_max-base_rectangle[0].vertex[1].x;
  1022.       rectangle[3].vertex[2].y=base_rectangle[0].vertex[1].y;
  1023.       rectangle[3].vertex[3].x=base_rectangle[0].vertex[1].x;
  1024.       rectangle[3].vertex[3].y=base_rectangle[0].vertex[1].y;
  1025.       for (y=0; y <= max_y-1; y+=4)
  1026.         {
  1027.           if (y > 0) 
  1028.             {
  1029.               display_quadrilateral(x_max,x_offset,y_max,
  1030.                rectangle[0].vertex[0].x,rectangle[0].vertex[0].y,0.0,
  1031.                rectangle[0].vertex[1].x,rectangle[0].vertex[1].y,0.0,
  1032.                rectangle[0].vertex[2].x,rectangle[0].vertex[2].y,0.0,
  1033.                rectangle[0].vertex[3].x,rectangle[0].vertex[3].y,0.0,
  1034.                pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  1035.                rel_dist_of_user_from_screen,FLOOR_COLOR);
  1036.               display_quadrilateral(x_max,x_offset,y_max,
  1037.                rectangle[1].vertex[0].x,rectangle[1].vertex[0].y,0.0,
  1038.                rectangle[1].vertex[1].x,rectangle[1].vertex[1].y,0.0,
  1039.                rectangle[1].vertex[2].x,rectangle[1].vertex[2].y,0.0,
  1040.                rectangle[1].vertex[3].x,rectangle[1].vertex[3].y,0.0,
  1041.                pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  1042.                rel_dist_of_user_from_screen,FLOOR_COLOR);
  1043.             }
  1044.           display_quadrilateral(x_max,x_offset,y_max,
  1045.            rectangle[2].vertex[0].x,rectangle[2].vertex[0].y,0.0,
  1046.            rectangle[2].vertex[1].x,rectangle[2].vertex[1].y,0.0,
  1047.            rectangle[2].vertex[2].x,rectangle[2].vertex[2].y,0.0,
  1048.            rectangle[2].vertex[3].x,rectangle[2].vertex[3].y,0.0,
  1049.            pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  1050.            rel_dist_of_user_from_screen,FLOOR_COLOR);
  1051.           if (y < max_y-4)
  1052.             {
  1053.               display_quadrilateral(x_max,x_offset,y_max,
  1054.                rectangle[3].vertex[0].x,rectangle[3].vertex[0].y,0.0,
  1055.                rectangle[3].vertex[1].x,rectangle[3].vertex[1].y,0.0,
  1056.                rectangle[3].vertex[2].x,rectangle[3].vertex[2].y,0.0,
  1057.                rectangle[3].vertex[3].x,rectangle[3].vertex[3].y,0.0,
  1058.                pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  1059.                rel_dist_of_user_from_screen,FLOOR_COLOR);
  1060.             }
  1061.           for (object_num=0; object_num < 4; object_num++)
  1062.             for (vertex_num=0; vertex_num < 4; vertex_num++)
  1063.               (rectangle[object_num].vertex[vertex_num].y)+=sqrt_3;
  1064.         }
  1065.       rectangle[0].vertex[0].x=base_triangle[1].vertex[0].x;
  1066.       rectangle[0].vertex[0].y=base_triangle[1].vertex[0].y;
  1067.       rectangle[0].vertex[1].x=base_triangle[1].vertex[1].x;
  1068.       rectangle[0].vertex[1].y=base_triangle[1].vertex[1].y;
  1069.       rectangle[0].vertex[2].x=base_triangle[2].vertex[1].x;
  1070.       rectangle[0].vertex[2].y=base_triangle[2].vertex[1].y;
  1071.       rectangle[0].vertex[3].x=base_triangle[2].vertex[2].x;
  1072.       rectangle[0].vertex[3].y=base_triangle[2].vertex[2].y;
  1073.       rectangle[1].vertex[0].x=base_triangle[0].vertex[1].x;
  1074.       rectangle[1].vertex[0].y=base_triangle[0].vertex[1].y;
  1075.       rectangle[1].vertex[1].x=base_triangle[1].vertex[0].x;
  1076.       rectangle[1].vertex[1].y=base_triangle[1].vertex[0].y;
  1077.       rectangle[1].vertex[2].x=base_triangle[2].vertex[2].x;
  1078.       rectangle[1].vertex[2].y=base_triangle[2].vertex[2].y;
  1079.       rectangle[1].vertex[3].x=base_triangle[3].vertex[1].x;
  1080.       rectangle[1].vertex[3].y=base_triangle[3].vertex[1].y;
  1081.       rectangle[2].vertex[0].x=base_triangle[0].vertex[0].x;
  1082.       rectangle[2].vertex[0].y=base_triangle[0].vertex[0].y;
  1083.       rectangle[2].vertex[1].x=base_triangle[0].vertex[1].x;
  1084.       rectangle[2].vertex[1].y=base_triangle[0].vertex[1].y;
  1085.       rectangle[2].vertex[2].x=base_triangle[3].vertex[1].x;
  1086.       rectangle[2].vertex[2].y=base_triangle[3].vertex[1].y;
  1087.       rectangle[2].vertex[3].x=base_triangle[3].vertex[2].x;
  1088.       rectangle[2].vertex[3].y=base_triangle[3].vertex[2].y;
  1089.       for (x=0; x <= max_x; x+=8)
  1090.         {
  1091.           for (object_num=0; object_num < 3; object_num++)
  1092.             {
  1093.               display_quadrilateral(x_max,x_offset,y_max,
  1094.                rectangle[object_num].vertex[0].x,
  1095.                rectangle[object_num].vertex[0].y,0.0,
  1096.                rectangle[object_num].vertex[1].x,
  1097.                rectangle[object_num].vertex[1].y,0.0,
  1098.                rectangle[object_num].vertex[2].x,
  1099.                rectangle[object_num].vertex[2].y,0.0,
  1100.                rectangle[object_num].vertex[3].x,
  1101.                rectangle[object_num].vertex[3].y,0.0,
  1102.                pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  1103.                rel_dist_of_user_from_screen,FLOOR_COLOR);
  1104.               display_quadrilateral(x_max,x_offset,y_max,
  1105.                rectangle[object_num].vertex[0].x,
  1106.                y_max-rectangle[object_num].vertex[0].y,0.0,
  1107.                rectangle[object_num].vertex[1].x,
  1108.                y_max-rectangle[object_num].vertex[1].y,0.0,
  1109.                rectangle[object_num].vertex[2].x,
  1110.                y_max-rectangle[object_num].vertex[2].y,0.0,
  1111.                rectangle[object_num].vertex[3].x,
  1112.                y_max-rectangle[object_num].vertex[3].y,0.0,
  1113.                pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  1114.                rel_dist_of_user_from_screen,FLOOR_COLOR);
  1115.               for (vertex_num=0; vertex_num < 4; vertex_num++)
  1116.                 (rectangle[object_num].vertex[vertex_num].x)+=3.0;
  1117.             }
  1118.         }
  1119.       y_mod_4=0;
  1120.       y_offset=0.0;
  1121.       for (y=0; y <= max_y; y++)
  1122.         {
  1123.           switch (y_mod_4)
  1124.             {
  1125.               case 0:
  1126.                 x_mod_8=0;
  1127.                 for (object_num=1; object_num <= 2; object_num++)
  1128.                   for (vertex_num=0; vertex_num < 3; vertex_num++)
  1129.                     {
  1130.                       triangle[object_num].vertex[vertex_num].x
  1131.                        =base_triangle[object_num].vertex[vertex_num].x;
  1132.                       triangle[object_num].vertex[vertex_num].y
  1133.                        =base_triangle[object_num].vertex[vertex_num].y
  1134.                        +y_offset;
  1135.                     }
  1136.                 for (vertex_num=0; vertex_num < 4; vertex_num++)
  1137.                   {
  1138.                     rectangle[2].vertex[vertex_num].x
  1139.                      =base_rectangle[2].vertex[vertex_num].x;
  1140.                     rectangle[2].vertex[vertex_num].y
  1141.                      =base_rectangle[2].vertex[vertex_num].y+y_offset;
  1142.                   }
  1143.                 for (x=0; x <= max_x; x++)
  1144.                   {
  1145.                     switch (x_mod_8)
  1146.                       {
  1147.                         case 2:
  1148.                           output_triangle(x_max,x_offset,y_max,&triangle[1],
  1149.                            pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  1150.                            rel_dist_of_user_from_screen,TRUE,
  1151.                            TRIANGLE_SSW_NNE_COLOR);
  1152.                           break;
  1153.                         case 4:
  1154.                           output_triangle(x_max,x_offset,y_max,&triangle[2],
  1155.                            pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  1156.                            rel_dist_of_user_from_screen,TRUE,
  1157.                            TRIANGLE_SSE_NNW_COLOR);
  1158.                           break;
  1159.                         default:
  1160.                           break;
  1161.                       }
  1162.                     if (++x_mod_8 >= 8)
  1163.                       {
  1164.                         x_mod_8=0;
  1165.                         for (object_num=1; object_num <= 2; object_num++)
  1166.                           for (vertex_num=0; vertex_num < 3; vertex_num++)
  1167.                             (triangle[object_num].vertex[vertex_num].x)+=3.0;
  1168.                         for (vertex_num=0; vertex_num < 4; vertex_num++)
  1169.                           (rectangle[2].vertex[vertex_num].x)+=3.0;
  1170.                       }
  1171.                   }
  1172.                 x_mod_8=0;
  1173.                 for (object_num=1; object_num <= 2; object_num++)
  1174.                   for (vertex_num=0; vertex_num < 3; vertex_num++)
  1175.                     {
  1176.                       triangle[object_num].vertex[vertex_num].x
  1177.                        =base_triangle[object_num].vertex[vertex_num].x;
  1178.                       triangle[object_num].vertex[vertex_num].y
  1179.                        =base_triangle[object_num].vertex[vertex_num].y
  1180.                        +y_offset;
  1181.                     }
  1182.                 for (vertex_num=0; vertex_num < 4; vertex_num++)
  1183.                   {
  1184.                     rectangle[2].vertex[vertex_num].x
  1185.                      =base_rectangle[2].vertex[vertex_num].x;
  1186.                     rectangle[2].vertex[vertex_num].y
  1187.                      =base_rectangle[2].vertex[vertex_num].y+y_offset;
  1188.                   }
  1189.                 for (x=0; x <= max_x; x++)
  1190.                   {
  1191.                     switch (x_mod_8)
  1192.                       {
  1193.                         case 2:
  1194.                           output_triangle(x_max,x_offset,y_max,&triangle[1],
  1195.                            pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  1196.                            rel_dist_of_user_from_screen,FALSE,
  1197.                            TRIANGLE_SE_NW_COLOR);
  1198.                           break;
  1199.                         case 3:
  1200.                           if (page[y][x] == 'W')
  1201.                             output_rectangle(x_max,x_offset,y_max,&rectangle[2],
  1202.                              pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  1203.                              rel_dist_of_user_from_screen,
  1204.                              RECTANGLE_W_E_COLOR);
  1205.                           break;
  1206.                         case 4:
  1207.                           output_triangle(x_max,x_offset,y_max,&triangle[2],
  1208.                            pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  1209.                            rel_dist_of_user_from_screen,FALSE,
  1210.                            TRIANGLE_SW_NE_COLOR);
  1211.                           break;
  1212.                         default:
  1213.                           break;
  1214.                       }
  1215.                     if (++x_mod_8 >= 8)
  1216.                       {
  1217.                         x_mod_8=0;
  1218.                         for (object_num=1; object_num <= 2; object_num++)
  1219.                           for (vertex_num=0; vertex_num < 3; vertex_num++)
  1220.                             (triangle[object_num].vertex[vertex_num].x)+=3.0;
  1221.                         for (vertex_num=0; vertex_num < 4; vertex_num++)
  1222.                           (rectangle[2].vertex[vertex_num].x)+=3.0;
  1223.                       }
  1224.                   }
  1225.                 break;
  1226.               case 1:
  1227.                 x_mod_8=0;
  1228.                 for (object_num=1; object_num <= 3; object_num+=2)
  1229.                   for (vertex_num=0; vertex_num < 4; vertex_num++)
  1230.                     {
  1231.                       rectangle[object_num].vertex[vertex_num].x
  1232.                        =base_rectangle[object_num].vertex[vertex_num].x;
  1233.                       rectangle[object_num].vertex[vertex_num].y
  1234.                        =base_rectangle[object_num].vertex[vertex_num].y
  1235.                        +y_offset;
  1236.                     }
  1237.                 for (x=0; x <= max_x; x++)
  1238.                   {
  1239.                     switch (x_mod_8)
  1240.                       {
  1241.                         case 1:
  1242.                           if (page[y][x] == 'W')
  1243.                             output_rectangle(x_max,x_offset,y_max,&rectangle[1],
  1244.                              pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  1245.                              rel_dist_of_user_from_screen,
  1246.                              RECTANGLE_SW_NE_COLOR);
  1247.                           break;
  1248.                         case 5:
  1249.                           if (page[y][x] == 'W')
  1250.                             output_rectangle(x_max,x_offset,y_max,&rectangle[3],
  1251.                              pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  1252.                              rel_dist_of_user_from_screen,
  1253.                              RECTANGLE_SE_NW_COLOR);
  1254.                           break;
  1255.                         default:
  1256.                           break;
  1257.                       }
  1258.                     if (++x_mod_8 >= 8)
  1259.                       {
  1260.                         x_mod_8=0;
  1261.                         for (object_num=1; object_num <= 3; object_num+=2)
  1262.                           for (vertex_num=0; vertex_num < 4; vertex_num++)
  1263.                             (rectangle[object_num].vertex[vertex_num].x)+=3.0;
  1264.                       }
  1265.                   }
  1266.                 break;
  1267.               case 2:
  1268.                 x_mod_8=0;
  1269.                 for (object_num=0; object_num <= 3; object_num+=3)
  1270.                   for (vertex_num=0; vertex_num < 3; vertex_num++)
  1271.                     {
  1272.                       triangle[object_num].vertex[vertex_num].x
  1273.                        =base_triangle[object_num].vertex[vertex_num].x;
  1274.                       triangle[object_num].vertex[vertex_num].y
  1275.                        =base_triangle[object_num].vertex[vertex_num].y
  1276.                        +y_offset;
  1277.                     }
  1278.                 for (vertex_num=0; vertex_num < 4; vertex_num++)
  1279.                   {
  1280.                     rectangle[4].vertex[vertex_num].x
  1281.                      =base_rectangle[4].vertex[vertex_num].x;
  1282.                     rectangle[4].vertex[vertex_num].y
  1283.                      =base_rectangle[4].vertex[vertex_num].y+y_offset;
  1284.                   }
  1285.                 for (x=0; x <= max_x; x++)
  1286.                   {
  1287.                     switch (x_mod_8)
  1288.                       {
  1289.                         case 0:
  1290.                           output_triangle(x_max,x_offset,y_max,&triangle[0],
  1291.                            pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  1292.                            rel_dist_of_user_from_screen,TRUE,
  1293.                            TRIANGLE_SSW_NNE_COLOR);
  1294.                           break;
  1295.                         case 6:
  1296.                           output_triangle(x_max,x_offset,y_max,&triangle[3],
  1297.                            pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  1298.                            rel_dist_of_user_from_screen,TRUE,
  1299.                            TRIANGLE_SSE_NNW_COLOR);
  1300.                           break;
  1301.                         default:
  1302.                           break;
  1303.                       }
  1304.                     if (++x_mod_8 >= 8)
  1305.                       {
  1306.                         x_mod_8=0;
  1307.                         for (object_num=0; object_num <= 3; object_num+=3)
  1308.                           for (vertex_num=0; vertex_num < 3; vertex_num++)
  1309.                             (triangle[object_num].vertex[vertex_num].x)+=3.0;
  1310.                         for (vertex_num=0; vertex_num < 4; vertex_num++)
  1311.                           (rectangle[4].vertex[vertex_num].x)+=3.0;
  1312.                       }
  1313.                   }
  1314.                 x_mod_8=0;
  1315.                 for (object_num=0; object_num <= 3; object_num+=3)
  1316.                   for (vertex_num=0; vertex_num < 3; vertex_num++)
  1317.                     {
  1318.                       triangle[object_num].vertex[vertex_num].x
  1319.                        =base_triangle[object_num].vertex[vertex_num].x;
  1320.                       triangle[object_num].vertex[vertex_num].y
  1321.                        =base_triangle[object_num].vertex[vertex_num].y
  1322.                        +y_offset;
  1323.                     }
  1324.                 for (vertex_num=0; vertex_num < 4; vertex_num++)
  1325.                   {
  1326.                     rectangle[4].vertex[vertex_num].x
  1327.                      =base_rectangle[4].vertex[vertex_num].x;
  1328.                     rectangle[4].vertex[vertex_num].y
  1329.                      =base_rectangle[4].vertex[vertex_num].y+y_offset;
  1330.                   }
  1331.                 for (x=0; x <= max_x; x++)
  1332.                   {
  1333.                     switch (x_mod_8)
  1334.                       {
  1335.                         case 0:
  1336.                           output_triangle(x_max,x_offset,y_max,&triangle[0],
  1337.                            pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  1338.                            rel_dist_of_user_from_screen,FALSE,
  1339.                            TRIANGLE_SW_NE_COLOR);
  1340.                           break;
  1341.                         case 6:
  1342.                           output_triangle(x_max,x_offset,y_max,&triangle[3],
  1343.                            pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  1344.                            rel_dist_of_user_from_screen,FALSE,
  1345.                            TRIANGLE_SE_NW_COLOR);
  1346.                           break;
  1347.                         case 7:
  1348.                           if (page[y][x] == 'W')
  1349.                             output_rectangle(x_max,x_offset,y_max,&rectangle[4],
  1350.                              pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  1351.                              rel_dist_of_user_from_screen,
  1352.                              RECTANGLE_W_E_COLOR);
  1353.                           break;
  1354.                         default:
  1355.                           break;
  1356.                       }
  1357.                     if (++x_mod_8 >= 8)
  1358.                       {
  1359.                         x_mod_8=0;
  1360.                         for (object_num=0; object_num <= 3; object_num+=3)
  1361.                           for (vertex_num=0; vertex_num < 3; vertex_num++)
  1362.                             (triangle[object_num].vertex[vertex_num].x)+=3.0;
  1363.                         for (vertex_num=0; vertex_num < 4; vertex_num++)
  1364.                           (rectangle[4].vertex[vertex_num].x)+=3.0;
  1365.                       }
  1366.                   }
  1367.                 break;
  1368.               default:
  1369.                 x_mod_8=0;
  1370.                 for (object_num=0; object_num <= 5; object_num+=5)
  1371.                   for (vertex_num=0; vertex_num < 4; vertex_num++)
  1372.                     {
  1373.                       rectangle[object_num].vertex[vertex_num].x
  1374.                        =base_rectangle[object_num].vertex[vertex_num].x;
  1375.                       rectangle[object_num].vertex[vertex_num].y
  1376.                        =base_rectangle[object_num].vertex[vertex_num].y
  1377.                        +y_offset;
  1378.                     }
  1379.                 for (x=0; x <= max_x; x++)
  1380.                   {
  1381.                     switch (x_mod_8)
  1382.                       {
  1383.                         case 1:
  1384.                           if (page[y][x] == 'W')
  1385.                             output_rectangle(x_max,x_offset,y_max,&rectangle[0],
  1386.                              pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  1387.                              rel_dist_of_user_from_screen,
  1388.                              RECTANGLE_SE_NW_COLOR);
  1389.                           break;
  1390.                         case 5:
  1391.                           if (page[y][x] == 'W')
  1392.                             output_rectangle(x_max,x_offset,y_max,&rectangle[5],
  1393.                              pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  1394.                              rel_dist_of_user_from_screen,
  1395.                              RECTANGLE_SW_NE_COLOR);
  1396.                           break;
  1397.                         default:
  1398.                           break;
  1399.                       }
  1400.                     if (++x_mod_8 >= 8)
  1401.                       {
  1402.                         x_mod_8=0;
  1403.                         for (object_num=0; object_num <= 5; object_num+=5)
  1404.                           for (vertex_num=0; vertex_num < 4; vertex_num++)
  1405.                             (rectangle[object_num].vertex[vertex_num].x)+=3.0;
  1406.                       }
  1407.                   }
  1408.                 break;
  1409.             }
  1410.           if (++y_mod_4 >= 4)
  1411.             {
  1412.               y_mod_4=0;
  1413.               y_offset+=sqrt_3;
  1414.             }
  1415.         }
  1416.       return;
  1417.     }
  1418.  
  1419. static int memory_allocated(
  1420.   char      ***computer_page,
  1421.   char      ***user_page,
  1422.   int       max_x_plus_1,
  1423.   int       max_y_plus_1,
  1424.   stack_rec **stack,
  1425.   int       num_rooms_in_maze)
  1426.     {
  1427.       static   int result;
  1428.       register int y;
  1429.  
  1430.       if (((*computer_page)
  1431.        =(char **) malloc(((size_t) max_y_plus_1)*sizeof(char *))) == NULL)
  1432.         result=FALSE;
  1433.       else
  1434.         {
  1435.           result=TRUE;
  1436.           for (y=0; ((result) && (y < max_y_plus_1)); y++)
  1437.            result=(((*computer_page)[y]
  1438.             =malloc(((size_t) max_x_plus_1)*sizeof(char))) != NULL);
  1439.           if (! result)
  1440.             {
  1441.               --y;
  1442.               while (y > 0)
  1443.                 free((void *) (*computer_page)[--y]);
  1444.               free((void *) *computer_page);
  1445.             }
  1446.         }
  1447.       if (result)
  1448.         {
  1449.           if (((*user_page)
  1450.            =(char **) malloc(((size_t) max_y_plus_1)*sizeof(char *))) == NULL)
  1451.             {
  1452.               result=FALSE;
  1453.               for (y=0; y < max_y_plus_1; y++)
  1454.                free((void *) (*computer_page)[y]);
  1455.               free((void *) *computer_page);
  1456.             }
  1457.           else
  1458.             {
  1459.               result=TRUE;
  1460.               for (y=0; ((result) && (y < max_y_plus_1)); y++)
  1461.                result=(((*user_page)[y]
  1462.                 =malloc(((size_t) max_x_plus_1)*sizeof(char))) != NULL);
  1463.               if (! result)
  1464.                 {
  1465.                   --y;
  1466.                   while (y > 0)
  1467.                     free((void *) (*user_page)[--y]);
  1468.                   free((void *) *user_page);
  1469.                   for (y=0; y < max_y_plus_1; y++)
  1470.                    free((void *) (*computer_page)[y]);
  1471.                   free((void *) *computer_page);
  1472.                 }
  1473.             }
  1474.         }
  1475.       if (result)
  1476.         {
  1477.           if ((*stack=(stack_rec *) malloc(
  1478.            ((unsigned int) num_rooms_in_maze)*sizeof(stack_rec))) == NULL)
  1479.             {
  1480.               result=FALSE;
  1481.               for (y=0; y < max_y_plus_1; y++)
  1482.                free((void *) (*user_page)[y]);
  1483.               free((void *) *user_page);
  1484.               for (y=0; y < max_y_plus_1; y++)
  1485.                free((void *) (*computer_page)[y]);
  1486.               free((void *) *computer_page);
  1487.             }
  1488.         }
  1489.       return(result);
  1490.     }
  1491.  
  1492. static void free_memory(
  1493.   char      ***computer_page,
  1494.   char      ***user_page,
  1495.   int       max_y_plus_1,
  1496.   stack_rec **stack)
  1497.     {
  1498.       register int y;
  1499.  
  1500.       free((void *) *stack);
  1501.       for (y=0; y < max_y_plus_1; y++)
  1502.         free((void *) (*user_page)[y]);
  1503.       free((void *) *user_page);
  1504.       for (y=0; y < max_y_plus_1; y++)
  1505.         free((void *) (*computer_page)[y]);
  1506.       free((void *) *computer_page);
  1507.       return;
  1508.     }
  1509.  
  1510. static void get_cursor(
  1511.   unsigned char *cursor_row,
  1512.   unsigned char *cursor_column,
  1513.   unsigned char *cursor_start,
  1514.   unsigned char *cursor_stop)
  1515.     {
  1516.       static union REGS in;
  1517.       static union REGS out;
  1518.  
  1519.       in.h.ah=(unsigned char) 3;
  1520.       in.h.bh=(unsigned char) 0;
  1521.       int86(0x10,&in,&out);
  1522.       *cursor_row=out.h.dh;
  1523.       *cursor_column=out.h.dl;
  1524.       *cursor_start=out.h.ch;
  1525.       *cursor_stop=out.h.cl;
  1526.       return;
  1527.     }
  1528.  
  1529. static void set_cursor_position(
  1530.   unsigned char cursor_row,
  1531.   unsigned char cursor_column)
  1532.     {
  1533.       static union REGS in;
  1534.       static union REGS out;
  1535.  
  1536.       in.h.ah=(unsigned char) 2;
  1537.       in.h.dh=cursor_row;
  1538.       in.h.dl=cursor_column;
  1539.       int86(0x10,&in,&out);
  1540.       return;
  1541.     }
  1542.  
  1543. static void set_cursor_size(
  1544.   unsigned char cursor_start,
  1545.   unsigned char cursor_stop)
  1546.     {
  1547.       static union REGS in;
  1548.       static union REGS out;
  1549.  
  1550.       in.h.ah=(unsigned char) 1;
  1551.       in.h.ch=cursor_start;
  1552.       in.h.cl=cursor_stop;
  1553.       int86(0x10,&in,&out);
  1554.       return;
  1555.     }
  1556.  
  1557. static void titillate()
  1558.     {
  1559.       set_cursor_position(cursor_row,cursor_column);
  1560.       titillator_index++;
  1561.       if (titillator_index > 3)
  1562.         titillator_index=0;
  1563.       putchar((int) titillator[titillator_index]);
  1564.       return;
  1565.     }
  1566.  
  1567. static void solve_maze(
  1568.   stack_rec *stack,
  1569.   char      **page,
  1570.   int       *num_rooms_in_solution,
  1571.   int       *adjacency,
  1572.   int       max_x,
  1573.   int       max_y)
  1574.     {
  1575.       int delta_index;
  1576.       int passage_found;
  1577.       int stack_head;
  1578.       int x;
  1579.       int x_next;
  1580.       int y;
  1581.       int y_next;
  1582.  
  1583.       *num_rooms_in_solution=1;
  1584.       *adjacency=0;
  1585.       x=3;
  1586.       y=2;
  1587.       stack_head=-1;
  1588.       page[y][x]='S';
  1589.       do
  1590.         {
  1591.           delta_index=0;
  1592.           passage_found=FALSE;
  1593.           do
  1594.             {
  1595.               while ((delta_index < 6) && (! passage_found))
  1596.                 {
  1597.                   x_next=x+delta_x[delta_index][0];
  1598.                   y_next=y+delta_y[delta_index][0];
  1599.                   if (page[y_next][x_next] == ' ')
  1600.                     passage_found=TRUE;
  1601.                   else
  1602.                     delta_index++;
  1603.                 }
  1604.               if (! passage_found)
  1605.                 {
  1606.                   delta_index=(int) (stack[stack_head].index_1);
  1607.                   page[y][x]=' ';
  1608.                   x-=delta_x[delta_index][0];
  1609.                   y-=delta_y[delta_index][0];
  1610.                   page[y][x]=' ';
  1611.                   x-=delta_x[delta_index][0];
  1612.                   y-=delta_y[delta_index][0];
  1613.                   stack_head--;
  1614.                   delta_index++;
  1615.                 }
  1616.             }
  1617.           while (! passage_found);
  1618.           page[y_next][x_next]='S';
  1619.           x_next+=delta_x[delta_index][0];
  1620.           y_next+=delta_y[delta_index][0];
  1621.           if (y_next <= max_y)
  1622.             {
  1623.               stack_head++;
  1624.               stack[stack_head].index_1=(char) delta_index;
  1625.               page[y_next][x_next]='S';
  1626.               x=x_next;
  1627.               y=y_next;
  1628.             }
  1629.         }
  1630.       while (y_next < max_y);
  1631.       x=max_x-3;
  1632.       y=max_y-2;
  1633.       *adjacency=0;
  1634.       while (stack_head >= 0)
  1635.         {
  1636.           for (delta_index=0; delta_index < 6; delta_index++)
  1637.             {
  1638.               x_next=x+delta_x[delta_index][0];
  1639.               y_next=y+delta_y[delta_index][0];
  1640.               if (page[y_next][x_next] != 'S')
  1641.                 {
  1642.                   if (page[y_next][x_next] == 'W')
  1643.                     {
  1644.                       x_next+=delta_x[delta_index][0];
  1645.                       y_next+=delta_y[delta_index][0];
  1646.                       if (x_next < 0)
  1647.                         (*adjacency)++;
  1648.                       else
  1649.                         if (x_next > max_x)
  1650.                           (*adjacency)++;
  1651.                         else
  1652.                           if (y_next < 0)
  1653.                             (*adjacency)++;
  1654.                           else
  1655.                             if (y_next > max_y)
  1656.                               (*adjacency)++;
  1657.                             else
  1658.                               {
  1659.                                 if (page[y_next][x_next] == 'S')
  1660.                                   (*adjacency)++;
  1661.                               }
  1662.                     }
  1663.                 }
  1664.             }
  1665.           x-=(2*delta_x[stack[stack_head].index_1][0]);
  1666.           y-=(2*delta_y[stack[stack_head].index_1][0]);
  1667.           stack_head--;
  1668.           (*num_rooms_in_solution)++;
  1669.         }
  1670.       for (delta_index=0; delta_index < 6; delta_index++)
  1671.         {
  1672.           x_next=x+delta_x[delta_index][0];
  1673.           y_next=y+delta_y[delta_index][0];
  1674.           if (page[y_next][x_next] != ' ')
  1675.             {
  1676.               if (page[y_next][x_next] == 'W')
  1677.                 {
  1678.                   x_next+=delta_x[delta_index][0];
  1679.                   y_next+=delta_y[delta_index][0];
  1680.                   if (x_next < 0)
  1681.                     (*adjacency)++;
  1682.                   else
  1683.                     if (x_next > max_x)
  1684.                       (*adjacency)++;
  1685.                     else
  1686.                       if (y_next < 0)
  1687.                         (*adjacency)++;
  1688.                       else
  1689.                         if (y_next > max_y)
  1690.                           (*adjacency)++;
  1691.                         else
  1692.                           {
  1693.                             if (page[y_next][x_next] == 'S')
  1694.                               (*adjacency)++;
  1695.                           }
  1696.                 }
  1697.             }
  1698.         }
  1699.       return;
  1700.     }
  1701.  
  1702. static void generate_maze(
  1703.   char      **page,
  1704.   int       max_x,
  1705.   int       max_y,
  1706.   stack_rec *stack,
  1707.   int       num_columns,
  1708.   int       num_rows,
  1709.   int       *seed)
  1710.     {
  1711.       static   int column_num;
  1712.       static   int delta_index_1;
  1713.       static   int delta_index_2;
  1714.       static   int passage_found;
  1715.       static   int r_n [8];
  1716.       register int r_n_index_1;
  1717.       register int r_n_index_2;
  1718.       static   int row_num;
  1719.       static   int search_complete;
  1720.       static   int stack_head;
  1721.       static   int tem_int;
  1722.       static   int x;
  1723.       static   int x_mod_8;
  1724.       static   int x_next;
  1725.       static   int y;
  1726.       static   int y_mod_4;
  1727.       static   int y_next;
  1728.  
  1729.       r_n[0]=seed[0]+1;
  1730.       r_n[1]=seed[1]+1;
  1731.       r_n[2]=seed[2]+1;
  1732.       r_n[3]=seed[3]+1;
  1733.       r_n[4]=seed[4]+1;
  1734.       r_n[5]=seed[5]+1;
  1735.       r_n[6]=seed[6]+1;
  1736.       r_n[7]=seed[7]+1;
  1737.       y_mod_4=1;
  1738.       for (y=0; y <= max_y; y++)
  1739.         {
  1740.           if (y_mod_4 == 1)
  1741.             {
  1742.               x_mod_8=1;
  1743.               for (x=0; x <= max_x; x++)
  1744.                 {
  1745.                   if (((x_mod_8 == 0)
  1746.                     && (y != 0)
  1747.                     && (y != max_y))
  1748.                   ||  (x_mod_8 == 3)
  1749.                   ||  (x_mod_8 == 4)
  1750.                   ||  (x_mod_8 == 5))
  1751.                     page[y][x]='W';
  1752.                   else
  1753.                     page[y][x]=' ';
  1754.                   x_mod_8++;
  1755.                   if (x_mod_8 >= 8)
  1756.                     x_mod_8=0;
  1757.                 }
  1758.             }
  1759.           else
  1760.             {
  1761.               if (y_mod_4 == 0 || y_mod_4 == 2)
  1762.                 {
  1763.                   x_mod_8=1;
  1764.                   for (x=0; x <= max_x; x++)
  1765.                     {
  1766.                       if ((x_mod_8 == 2) || (x_mod_8 == 6))
  1767.                         page[y][x]='W';
  1768.                       else
  1769.                         page[y][x]=' ';
  1770.                       x_mod_8++;
  1771.                       if (x_mod_8 >= 8)
  1772.                         x_mod_8=0;
  1773.                     }
  1774.                 }
  1775.               else
  1776.                 {
  1777.                   x_mod_8=1;
  1778.                   for (x=0; x <= max_x; x++)
  1779.                     {
  1780.                       if ((x_mod_8 == 0)
  1781.                       ||  (x_mod_8 == 1)
  1782.                       ||  (x_mod_8 == 4)
  1783.                       ||  (x_mod_8 == 7))
  1784.                         page[y][x]='W';
  1785.                       else
  1786.                         page[y][x]=' ';
  1787.                       x_mod_8++;
  1788.                       if (x_mod_8 >= 8)
  1789.                         x_mod_8=0;
  1790.                   }
  1791.                 }
  1792.             }
  1793.           y_mod_4++;
  1794.           if (y_mod_4 >= 4)
  1795.             y_mod_4=0;
  1796.         }
  1797.       column_num=r_n[0];
  1798.       r_n_index_1=0;
  1799.       r_n_index_2=1;
  1800.       while (r_n_index_2 < 8)
  1801.         {
  1802.           tem_int=r_n[r_n_index_2];
  1803.           r_n[r_n_index_1]=tem_int;
  1804.           column_num+=tem_int;
  1805.           if (column_num >= 727)
  1806.             column_num-=727;
  1807.           r_n_index_1=r_n_index_2;
  1808.           r_n_index_2++;
  1809.         }
  1810.       r_n[7]=column_num;
  1811.       column_num%=num_columns;
  1812.       x=4*column_num+3;
  1813.       row_num=r_n[0];
  1814.       r_n_index_1=0;
  1815.       r_n_index_2=1;
  1816.       while (r_n_index_2 < 8)
  1817.         {
  1818.           tem_int=r_n[r_n_index_2];
  1819.           r_n[r_n_index_1]=tem_int;
  1820.           row_num+=tem_int;
  1821.           if (row_num >= 727)
  1822.             row_num-=727;
  1823.           r_n_index_1=r_n_index_2;
  1824.           r_n_index_2++;
  1825.         }
  1826.       r_n[7]=row_num;
  1827.       if (column_num%2)
  1828.         {
  1829.           row_num%=(num_rows-1);
  1830.           y=4*row_num+4;
  1831.         }
  1832.       else
  1833.         {
  1834.           row_num%=num_rows;
  1835.           y=4*row_num+2;
  1836.         }
  1837.       page[y][x]=' ';
  1838.       stack_head=-1;
  1839.       do
  1840.         {
  1841.           delta_index_1=0;
  1842.           do
  1843.             {
  1844.               delta_index_2=r_n[0];
  1845.               r_n_index_1=0;
  1846.               r_n_index_2=1;
  1847.               while (r_n_index_2 < 8)
  1848.                 {
  1849.                   tem_int=r_n[r_n_index_2];
  1850.                   r_n[r_n_index_1]=tem_int;
  1851.                   delta_index_2+=tem_int;
  1852.                   if (delta_index_2 >= 727)
  1853.                     delta_index_2-=727;
  1854.                   r_n_index_1=r_n_index_2;
  1855.                   r_n_index_2++;
  1856.                 }
  1857.               r_n[7]=delta_index_2;
  1858.             }
  1859.           while (delta_index_2 >= 720);
  1860.           passage_found=FALSE;
  1861.           search_complete=FALSE;
  1862.           while (! search_complete)
  1863.             {
  1864.               while ((delta_index_1 < 6) && (! passage_found))
  1865.                 {
  1866.                   x_next=x+2*delta_x[delta_index_1][delta_index_2];
  1867.                   if (x_next <= 0)
  1868.                     delta_index_1++;
  1869.                   else
  1870.                     if (x_next > max_x)
  1871.                       delta_index_1++;
  1872.                     else
  1873.                       {
  1874.                         y_next=y+2*delta_y[delta_index_1][delta_index_2];
  1875.                         if (y_next <= 0)
  1876.                           delta_index_1++;
  1877.                         else
  1878.                           if (y_next > max_y)
  1879.                             delta_index_1++;
  1880.                           else
  1881.                             if (page[y_next][x_next] == 'W')
  1882.                               passage_found=TRUE;
  1883.                             else
  1884.                               delta_index_1++;
  1885.                       }
  1886.                 }
  1887.               if (! passage_found)
  1888.                 {
  1889.                   if (stack_head >= 0)
  1890.                     {
  1891.                       delta_index_1=(int) (stack[stack_head].index_1);
  1892.                       delta_index_2=stack[stack_head].index_2;
  1893.                       x-=2*delta_x[delta_index_1][delta_index_2];
  1894.                       y-=2*delta_y[delta_index_1][delta_index_2];
  1895.                       stack_head--;
  1896.                       delta_index_1++;
  1897.                     }
  1898.                 }
  1899.               search_complete=((passage_found)
  1900.                || ((stack_head == -1) && (delta_index_1 >= 6)));
  1901.             }
  1902.           if (passage_found)
  1903.             {
  1904.               stack_head++;
  1905.               stack[stack_head].index_1=(char) delta_index_1;
  1906.               stack[stack_head].index_2=delta_index_2;
  1907.               page[y_next][x_next]=' ';
  1908.               page[(y+y_next)/2][(x+x_next)/2]=' ';
  1909.               x=x_next;
  1910.               y=y_next;
  1911.             }
  1912.         }
  1913.       while (stack_head != -1);
  1914.       page[0][3]='S';
  1915.       page[max_y][max_x-3]=' ';
  1916.       return;
  1917.     }
  1918.  
  1919. static void select_maze(
  1920.   char      *seed_ptr,
  1921.   char      **page,
  1922.   int       max_x,
  1923.   int       max_y,
  1924.   stack_rec *stack,
  1925.   int       num_rooms_in_maze,
  1926.   int       num_columns,
  1927.   int       num_rows,
  1928.   long      num_trials)
  1929.     {                 
  1930.       static   int    adjacency;
  1931.       static   int    counter_0;
  1932.       static   int    counter_1;
  1933.       static   int    counter_2;
  1934.       static   int    counter_3;
  1935.       static   int    counter_4;
  1936.       static   int    counter_5;
  1937.       static   int    counter_6;
  1938.       static   int    counter_7;
  1939.       static   int    min_adjacency;
  1940.       static   int    num_rooms_in_solution;
  1941.       static   int    num_rooms_in_solution_at_min;
  1942.       static   int    r_n [8];
  1943.       register int    r_n_index_1;
  1944.       register int    r_n_index_2;
  1945.       static   int    seed [8];
  1946.       static   int    seed_at_min [8];
  1947.       static   long   trial_num;
  1948.  
  1949.       while ((*seed_ptr == ' ')
  1950.       ||     (*seed_ptr == (char) 9))
  1951.         seed_ptr++;
  1952.       r_n_index_1=0;
  1953.       while ((r_n_index_1 < 8) && (*seed_ptr) && (*seed_ptr != '\n'))
  1954.         r_n[r_n_index_1++]=(int) (*(seed_ptr++) % 10);
  1955.       r_n_index_2=7;
  1956.       while (r_n_index_1 > 0)
  1957.         {
  1958.            r_n_index_1--;
  1959.            r_n[r_n_index_2]=r_n[r_n_index_1];
  1960.            r_n_index_2--;
  1961.         }
  1962.       while (r_n_index_2 >= 0)
  1963.         {
  1964.           r_n[r_n_index_2]=8;
  1965.           r_n_index_2--;
  1966.         }
  1967.       counter_0=r_n[0];
  1968.       counter_1=r_n[1];
  1969.       counter_2=r_n[2];
  1970.       counter_3=r_n[3];
  1971.       counter_4=r_n[4];
  1972.       counter_5=r_n[5];
  1973.       counter_6=r_n[6];
  1974.       counter_7=r_n[7];
  1975.       hash(&counter_0,&counter_1,&counter_2,&counter_3,&counter_4,&counter_5,
  1976.        &counter_6,&counter_7);
  1977.       get_cursor(&cursor_row,&cursor_column,&cursor_start,&cursor_stop);
  1978.       set_cursor_size((unsigned char) 32,(unsigned char) 32);
  1979.       titillator_index=0;
  1980.       min_adjacency=4*num_rooms_in_maze+1;
  1981.       num_rooms_in_solution_at_min=0;
  1982.       seed_at_min[0]=counter_0;
  1983.       seed_at_min[1]=counter_1;
  1984.       seed_at_min[2]=counter_2;
  1985.       seed_at_min[3]=counter_3;
  1986.       seed_at_min[4]=counter_4;
  1987.       seed_at_min[5]=counter_5;
  1988.       seed_at_min[6]=counter_6;
  1989.       seed_at_min[7]=counter_7;
  1990.       for (trial_num=num_trials; trial_num > 0L; --trial_num)
  1991.         {
  1992.           titillate();
  1993.           seed[0]=counter_0;
  1994.           seed[1]=counter_1;
  1995.           seed[2]=counter_2;
  1996.           seed[3]=counter_3;
  1997.           seed[4]=counter_4;
  1998.           seed[5]=counter_5;
  1999.           seed[6]=counter_6;
  2000.           seed[7]=counter_7;
  2001.           generate_maze(page,max_x,max_y,stack,num_columns,num_rows,&seed[0]);
  2002.           solve_maze(stack,page,&num_rooms_in_solution,&adjacency,max_x,max_y);
  2003.           if (3*num_rooms_in_solution >= num_rooms_in_maze)
  2004.             {
  2005.               if (adjacency < min_adjacency)
  2006.                 {
  2007.                   min_adjacency=adjacency;
  2008.                   num_rooms_in_solution_at_min=num_rooms_in_solution;
  2009.                   seed_at_min[0]=seed[0];
  2010.                   seed_at_min[1]=seed[1];
  2011.                   seed_at_min[2]=seed[2];
  2012.                   seed_at_min[3]=seed[3];
  2013.                   seed_at_min[4]=seed[4];
  2014.                   seed_at_min[5]=seed[5];
  2015.                   seed_at_min[6]=seed[6];
  2016.                   seed_at_min[7]=seed[7];
  2017.                 }
  2018.               else
  2019.                 {
  2020.                   if (adjacency == min_adjacency)
  2021.                     {
  2022.                       if (num_rooms_in_solution > num_rooms_in_solution_at_min)
  2023.                         {
  2024.                           num_rooms_in_solution_at_min=num_rooms_in_solution;
  2025.                           seed_at_min[0]=seed[0];
  2026.                           seed_at_min[1]=seed[1];
  2027.                           seed_at_min[2]=seed[2];
  2028.                           seed_at_min[3]=seed[3];
  2029.                           seed_at_min[4]=seed[4];
  2030.                           seed_at_min[5]=seed[5];
  2031.                           seed_at_min[6]=seed[6];
  2032.                           seed_at_min[7]=seed[7];
  2033.                         }
  2034.                     }
  2035.                 }
  2036.             }
  2037.           increment(&counter_0,&counter_1,&counter_2,&counter_3,&counter_4,
  2038.            &counter_5,&counter_6,&counter_7);
  2039.         }
  2040.       generate_maze(page,max_x,max_y,stack,num_columns,num_rows,
  2041.        &seed_at_min[0]);
  2042.       solve_maze(stack,page,&num_rooms_in_solution,&adjacency,max_x,max_y);
  2043.       return;
  2044.     }
  2045.  
  2046. static int substitution_high [100] =
  2047.              { 4,1,2,8,8,9,9,6,5,7,2,1,2,9,8,8,6,3,5,1,9,5,4,4,9,8,6,0,8,0,
  2048.                6,0,2,4,1,9,2,0,7,4,7,3,0,0,2,6,8,9,4,0,8,3,2,3,2,5,2,4,6,9,
  2049.                7,9,1,3,5,7,1,1,4,5,8,1,6,0,5,7,8,2,3,3,7,3,5,1,7,5,4,0,3,6,
  2050.                3,7,7,1,9,4,0,5,6,6
  2051.              };
  2052. static int substitution_low [100] =
  2053.              { 1,2,2,1,5,5,4,6,4,6,4,4,5,6,6,3,0,9,6,5,7,2,0,9,3,4,2,3,9,1,
  2054.                9,9,9,3,8,9,3,4,1,5,0,5,2,7,0,8,8,0,4,5,0,3,6,8,1,7,8,8,7,1,
  2055.                3,2,7,7,1,8,0,3,7,5,2,6,4,0,9,9,7,7,4,6,2,0,0,1,7,3,6,6,1,1,
  2056.                2,4,5,9,8,2,8,8,3,5
  2057.              };
  2058. static void hash(
  2059.   int *counter_0,
  2060.   int *counter_1,
  2061.   int *counter_2,
  2062.   int *counter_3,
  2063.   int *counter_4,
  2064.   int *counter_5,
  2065.   int *counter_6,
  2066.   int *counter_7)
  2067.     {
  2068.       register int iteration;
  2069.       static   int seed_0;
  2070.       static   int seed_1;
  2071.       static   int seed_2;
  2072.       static   int seed_3;
  2073.       static   int seed_4;
  2074.       static   int seed_5;
  2075.       static   int seed_6;
  2076.       static   int seed_7;
  2077.       register int substitution_index;
  2078.       static   int tem_0;
  2079.       static   int tem_1;
  2080.       static   int tem_2;
  2081.  
  2082.       seed_0=(*counter_0);
  2083.       seed_1=(*counter_1);
  2084.       seed_2=(*counter_2);
  2085.       seed_3=(*counter_3);
  2086.       seed_4=(*counter_4);
  2087.       seed_5=(*counter_5);
  2088.       seed_6=(*counter_6);
  2089.       seed_7=(*counter_7);
  2090.       for (iteration=1; iteration <= 8; iteration++)
  2091.         {
  2092.           substitution_index=10*seed_1+seed_0;
  2093.           tem_0=substitution_low[substitution_index];
  2094.           tem_1=substitution_high[substitution_index];
  2095.           substitution_index=10*seed_3+seed_2;
  2096.           seed_0=substitution_low[substitution_index];
  2097.           tem_2=substitution_high[substitution_index];
  2098.           substitution_index=10*seed_5+seed_4;
  2099.           seed_2=substitution_low[substitution_index];
  2100.           seed_1=substitution_high[substitution_index];
  2101.           substitution_index=10*seed_7+seed_6;
  2102.           seed_5=substitution_low[substitution_index];
  2103.           seed_7=substitution_high[substitution_index];
  2104.           seed_3=tem_0;
  2105.           seed_6=tem_1;
  2106.           seed_4=tem_2;
  2107.         }
  2108.       (*counter_0)=seed_0;
  2109.       (*counter_1)=seed_1;
  2110.       (*counter_2)=seed_2;
  2111.       (*counter_3)=seed_3;
  2112.       (*counter_4)=seed_4;
  2113.       (*counter_5)=seed_5;
  2114.       (*counter_6)=seed_6;
  2115.       (*counter_7)=seed_7;
  2116.       return;
  2117.     }
  2118.  
  2119. static void increment(
  2120.   int *counter_0,
  2121.   int *counter_1,
  2122.   int *counter_2,
  2123.   int *counter_3,
  2124.   int *counter_4,
  2125.   int *counter_5,
  2126.   int *counter_6,
  2127.   int *counter_7)
  2128.     {
  2129.       register tem;
  2130.  
  2131.       tem=(*counter_0)+1;
  2132.       if (tem <= 9)
  2133.         (*counter_0)=tem;
  2134.       else
  2135.         {
  2136.           (*counter_0)=0;
  2137.           tem=(*counter_1)+1;
  2138.           if (tem <= 9)
  2139.             (*counter_1)=tem;
  2140.           else
  2141.             {
  2142.               (*counter_1)=0;
  2143.               tem=(*counter_2)+1;
  2144.               if (tem <= 9)
  2145.                 (*counter_2)=tem;
  2146.               else
  2147.                 {
  2148.                   (*counter_2)=0;
  2149.                   tem=(*counter_3)+1;
  2150.                   if (tem <= 9)
  2151.                     (*counter_3)=tem;
  2152.                   else
  2153.                     {
  2154.                       (*counter_3)=0;
  2155.                       tem=(*counter_4)+1;
  2156.                       if (tem <= 9)
  2157.                         (*counter_4)=tem;
  2158.                       else
  2159.                         {
  2160.                           (*counter_4)=0;
  2161.                           tem=(*counter_5)+1;
  2162.                           if (tem <= 9)
  2163.                             (*counter_5)=tem;
  2164.                           else
  2165.                             {
  2166.                               (*counter_5)=0;
  2167.                               tem=(*counter_6)+1;
  2168.                               if (tem <= 9)
  2169.                                 (*counter_6)=tem;
  2170.                               else
  2171.                                 {
  2172.                                   (*counter_6)=0;
  2173.                                   tem=(*counter_7)+1;
  2174.                                   if (tem <= 9)
  2175.                                     (*counter_7)=tem;
  2176.                                   else
  2177.                                     (*counter_7)=0;
  2178.                                 }
  2179.                             }
  2180.                         }
  2181.                     }
  2182.                 }
  2183.             }
  2184.         }
  2185.       return;
  2186.     }
  2187.  
  2188. static void draw_line(
  2189.   double x1,
  2190.   double y1,
  2191.   double x2,
  2192.   double y2,
  2193.   double x_max,
  2194.   double x_offset,
  2195.   double y_max,
  2196.   double cos_tilt,
  2197.   double sin_tilt,
  2198.   double pixels_per_x,
  2199.   double pixels_per_z,
  2200.   double rel_dist_of_user_from_screen)
  2201.     {
  2202.       static corner_rec end_point [2];
  2203.  
  2204.       get_corner(x1,y1,RELATIVE_HEIGHT_OF_WALL,pixels_per_x,pixels_per_z,
  2205.        cos_tilt,sin_tilt,rel_dist_of_user_from_screen,x_max,x_offset,y_max,
  2206.        &end_point[0]);
  2207.       get_corner(x2,y2,RELATIVE_HEIGHT_OF_WALL,pixels_per_x,pixels_per_z,
  2208.        cos_tilt,sin_tilt,rel_dist_of_user_from_screen,x_max,x_offset,y_max,
  2209.        &end_point[1]);
  2210.       moveto(end_point[0].x,end_point[0].y);
  2211.       lineto(end_point[1].x,end_point[1].y);
  2212.       return;
  2213.     }
  2214.  
  2215. static void display_solution(
  2216.   int    max_y,
  2217.   char   **page,
  2218.   double x_max,
  2219.   double x_offset,
  2220.   double y_max,
  2221.   double cos_tilt,
  2222.   double sin_tilt,
  2223.   double pixels_per_x,
  2224.   double pixels_per_z,
  2225.   double rel_dist_of_user_from_screen)
  2226.     {
  2227.       static int    delta_index;
  2228.       static int    path_found;
  2229.       static int    x;
  2230.       static int    x_next;
  2231.       static int    x_previous;
  2232.       static double x_relative;
  2233.       static double x_relative_next;
  2234.       static int    y;
  2235.       static int    y_next;
  2236.       static int    y_previous;
  2237.       static double y_relative;
  2238.       static double y_relative_next;
  2239.  
  2240.       setlinestyle(SOLID_LINE,0xffff,THICK_WIDTH);
  2241.       setcolor(SOLUTION_COLOR);
  2242.       x_relative=1.0;
  2243.       y_relative=sqrt_3/2.0;
  2244.       draw_line(1.0,0.0,x_relative,y_relative,x_max,x_offset,y_max,cos_tilt,
  2245.        sin_tilt,pixels_per_x,pixels_per_z,rel_dist_of_user_from_screen);
  2246.       x_previous=3;
  2247.       y_previous=-2;
  2248.       x=3;
  2249.       y=2;
  2250.       do
  2251.         {
  2252.           path_found=FALSE;
  2253.           delta_index=0;
  2254.           while (! path_found)
  2255.             {
  2256.               x_next=x+delta_x[delta_index][0];
  2257.               y_next=y+delta_y[delta_index][0];
  2258.               if (page[y_next][x_next] == 'S')
  2259.                 {
  2260.                   x_next+=delta_x[delta_index][0];
  2261.                   y_next+=delta_y[delta_index][0];
  2262.                   if ((x_next != x_previous) || (y_next != y_previous))
  2263.                     path_found=TRUE;
  2264.                   else
  2265.                     delta_index++;
  2266.                 }
  2267.               else
  2268.                 delta_index++;
  2269.             }
  2270.           if (y_next < max_y)
  2271.             {
  2272.               switch (y_next-y)
  2273.                 {
  2274.                   case -4:
  2275.                     x_relative_next=x_relative;
  2276.                     y_relative_next=y_relative-sqrt_3;
  2277.                     break;
  2278.                   case -2:
  2279.                     if (x_next > x)
  2280.                       {
  2281.                         x_relative_next=x_relative+3.0/2.0;
  2282.                         y_relative_next=y_relative-sqrt_3/2.0;
  2283.                       }
  2284.                     else
  2285.                       {
  2286.                         x_relative_next=x_relative-3.0/2.0;
  2287.                         y_relative_next=y_relative-sqrt_3/2.0;
  2288.                       }
  2289.                     break;
  2290.                   case 2:
  2291.                     if (x_next > x)
  2292.                       {
  2293.                         x_relative_next=x_relative+3.0/2.0;
  2294.                         y_relative_next=y_relative+sqrt_3/2.0;
  2295.                       }
  2296.                     else
  2297.                       {
  2298.                         x_relative_next=x_relative-3.0/2.0;
  2299.                         y_relative_next=y_relative+sqrt_3/2.0;
  2300.                       }
  2301.                     break;
  2302.                   default:
  2303.                     x_relative_next=x_relative;
  2304.                     y_relative_next=y_relative+sqrt_3;
  2305.                     break;
  2306.                 }
  2307.               draw_line(x_relative,y_relative,x_relative_next,
  2308.                y_relative_next,x_max,x_offset,y_max,cos_tilt,sin_tilt,
  2309.                pixels_per_x,pixels_per_z,rel_dist_of_user_from_screen);
  2310.             }
  2311.           else
  2312.             draw_line(x_relative,y_relative,x_max-1.0,y_max,x_max,x_offset,
  2313.              y_max,cos_tilt,sin_tilt,pixels_per_x,pixels_per_z,
  2314.              rel_dist_of_user_from_screen);
  2315.           x_previous=x;
  2316.           y_previous=y;
  2317.           x=x_next;
  2318.           y=y_next;
  2319.           x_relative=x_relative_next;
  2320.           y_relative=y_relative_next;
  2321.         }
  2322.       while (y_next < max_y);
  2323.       return;
  2324.     }
  2325.  
  2326. static void let_user_try_to_solve(
  2327.   int    *key_pressed,
  2328.   int    max_x,
  2329.   int    max_y,
  2330.   char   **computer_page,
  2331.   char   **user_page,
  2332.   double x_max,
  2333.   double x_offset,
  2334.   double y_max,
  2335.   double cos_tilt,
  2336.   double sin_tilt,
  2337.   double pixels_per_x,
  2338.   double pixels_per_z,
  2339.   double rel_dist_of_user_from_screen)
  2340.     {
  2341.       static int    delta_index_1;
  2342.       static int    frequency;
  2343.       static int    passage_found;
  2344.       static int    x;
  2345.       static int    x_next;
  2346.       static double x_relative;
  2347.       static double x_relative_next;
  2348.       static int    y;
  2349.       static int    y_next;
  2350.       static double y_relative;
  2351.       static double y_relative_next;
  2352.  
  2353.       setlinestyle(SOLID_LINE,0xffff,NORM_WIDTH);
  2354.       for (x=0; x <= max_x; x++)
  2355.         for (y=0; y <= max_y; y++)
  2356.           if (computer_page[y][x] == 'W')
  2357.             user_page[y][x]='W';
  2358.           else
  2359.             user_page[y][x]=' ';
  2360.       x=3;
  2361.       y=2;
  2362.       user_page[y][x]='S';
  2363.       x_relative=1.0;
  2364.       y_relative=sqrt_3/2.0;
  2365.       setcolor(ADVANCE_COLOR);
  2366.       draw_line(1.0,0.0,x_relative,y_relative,x_max,x_offset,y_max,cos_tilt,
  2367.        sin_tilt,pixels_per_x,pixels_per_z,rel_dist_of_user_from_screen);
  2368.       do
  2369.         {
  2370.           do
  2371.             {
  2372.               passage_found=TRUE;
  2373.               *key_pressed=getch();
  2374.               if ((*key_pressed != (int) 'Q')
  2375.               &&  (*key_pressed != (int) 'q')
  2376.               &&  (*key_pressed != (int) 'S')
  2377.               &&  (*key_pressed != (int) 's'))
  2378.                 {
  2379.                   if (*key_pressed == 0)
  2380.                     {
  2381.                       *key_pressed=getch();
  2382.                       switch (*key_pressed)
  2383.                         {
  2384.                           case 71:
  2385.                              delta_index_1=0;
  2386.                              break;
  2387.                           case 72:
  2388.                              delta_index_1=2;
  2389.                              break;
  2390.                           case 73:
  2391.                              delta_index_1=4;
  2392.                              break;
  2393.                           case 79:
  2394.                              delta_index_1=1;
  2395.                              break;
  2396.                           case 80:
  2397.                              delta_index_1=3;
  2398.                              break;
  2399.                           case 81:
  2400.                              delta_index_1=5;
  2401.                              break;
  2402.                           default:
  2403.                             {
  2404.                               passage_found=FALSE;
  2405.                               sound(120);
  2406.                               delay(278);
  2407.                               nosound();
  2408.                               break;
  2409.                             }
  2410.                         }
  2411.                       *key_pressed=0;
  2412.                     }
  2413.                   else
  2414.                     {
  2415.                       switch (*key_pressed)
  2416.                         {
  2417.                           case 49:
  2418.                             delta_index_1=1;
  2419.                             break;
  2420.                           case 50:
  2421.                             delta_index_1=3;
  2422.                             break;
  2423.                           case 51:
  2424.                             delta_index_1=5;
  2425.                             break;
  2426.                           case 55:
  2427.                             delta_index_1=0;
  2428.                             break;
  2429.                           case 56:
  2430.                             delta_index_1=2;
  2431.                             break;
  2432.                           case 57:
  2433.                             delta_index_1=4;
  2434.                             break;
  2435.                           default:
  2436.                             passage_found=FALSE;
  2437.                             break;
  2438.                         }
  2439.                     }
  2440.                   if (passage_found)
  2441.                     {
  2442.                       x_next=x+delta_x[delta_index_1][0];
  2443.                       if (x_next <= 0)
  2444.                         passage_found=FALSE;
  2445.                       else
  2446.                         if (x_next >= max_x)
  2447.                           passage_found=FALSE;
  2448.                         else
  2449.                           {
  2450.                             y_next=y+delta_y[delta_index_1][0];
  2451.                             if (y_next <= 0)
  2452.                               passage_found=FALSE;
  2453.                             else
  2454.                               if (y_next > max_y)
  2455.                                 passage_found=FALSE;
  2456.                               else
  2457.                                 if (user_page[y_next][x_next] == 'W')
  2458.                                   passage_found=FALSE;
  2459.                           }
  2460.                     }
  2461.                   if (! passage_found)
  2462.                     {
  2463.                       passage_found=FALSE;
  2464.                       sound(120);
  2465.                       delay(278);
  2466.                       nosound();
  2467.                     }
  2468.                 }
  2469.             }
  2470.           while ((! passage_found)
  2471.           &&     (*key_pressed != (int) 'Q')
  2472.           &&     (*key_pressed != (int) 'q')
  2473.           &&     (*key_pressed != (int) 'S')
  2474.           &&     (*key_pressed != (int) 's'));
  2475.           if ((*key_pressed != (int) 'Q')
  2476.           &&  (*key_pressed != (int) 'q')
  2477.           &&  (*key_pressed != (int) 'S')
  2478.           &&  (*key_pressed != (int) 's'))
  2479.             {
  2480.               x_next+=delta_x[delta_index_1][0];
  2481.               y_next+=delta_y[delta_index_1][0];
  2482.               if (y_next < max_y)
  2483.                 {
  2484.                   if (user_page[y_next][x_next] == 'S')
  2485.                     {
  2486.                       setcolor(BACKOUT_COLOR);
  2487.                       user_page[y][x]=' ';
  2488.                     }
  2489.                   else
  2490.                     {
  2491.                       setcolor(ADVANCE_COLOR);
  2492.                       user_page[y_next][x_next]='S';
  2493.                     }
  2494.                   switch (y_next-y)
  2495.                     {
  2496.                       case -4:
  2497.                         x_relative_next=x_relative;
  2498.                         y_relative_next=y_relative-sqrt_3;
  2499.                         break;
  2500.                       case -2:
  2501.                         if (x_next > x)
  2502.                           {
  2503.                             x_relative_next=x_relative+3.0/2.0;
  2504.                             y_relative_next=y_relative-sqrt_3/2.0;
  2505.                           }
  2506.                         else
  2507.                           {
  2508.                             x_relative_next=x_relative-3.0/2.0;
  2509.                             y_relative_next=y_relative-sqrt_3/2.0;
  2510.                           }
  2511.                         break;
  2512.                       case 2:
  2513.                         if (x_next > x)
  2514.                           {
  2515.                             x_relative_next=x_relative+3.0/2.0;
  2516.                             y_relative_next=y_relative+sqrt_3/2.0;
  2517.                           }
  2518.                         else
  2519.                           {
  2520.                             x_relative_next=x_relative-3.0/2.0;
  2521.                             y_relative_next=y_relative+sqrt_3/2.0;
  2522.                           }
  2523.                         break;
  2524.                       default:
  2525.                         x_relative_next=x_relative;
  2526.                         y_relative_next=y_relative+sqrt_3;
  2527.                         break;
  2528.                     }
  2529.                   draw_line(x_relative,y_relative,x_relative_next,
  2530.                    y_relative_next,x_max,x_offset,y_max,cos_tilt,sin_tilt,
  2531.                    pixels_per_x,pixels_per_z,rel_dist_of_user_from_screen);
  2532.                 }
  2533.               else
  2534.                 {
  2535.                   setcolor(ADVANCE_COLOR);
  2536.                   draw_line(x_relative,y_relative,x_max-1.0,y_max,
  2537.                    x_max,x_offset,y_max,cos_tilt,sin_tilt,pixels_per_x,
  2538.                    pixels_per_z,rel_dist_of_user_from_screen);
  2539.                 }
  2540.               x=x_next;
  2541.               y=y_next;
  2542.               x_relative=x_relative_next;
  2543.               y_relative=y_relative_next;
  2544.             }
  2545.         }
  2546.       while ((y_next < max_y)
  2547.       &&     (*key_pressed != (int) 'Q')
  2548.       &&     (*key_pressed != (int) 'q')
  2549.       &&     (*key_pressed != (int) 'S')
  2550.       &&     (*key_pressed != (int) 's'));
  2551.       setcolor(0);
  2552.       outtextxy(NUM_X_PIXELS/2,NUM_Y_PIXELS-1,
  2553.        "Home PgUp PgDn End \030 \031 - Move    S - Solve    Q - Quit");
  2554.       if    ((*key_pressed != (int) 'Q')
  2555.       &&     (*key_pressed != (int) 'q')
  2556.       &&     (*key_pressed != (int) 'S')
  2557.       &&     (*key_pressed != (int) 's'))
  2558.         {
  2559.           setcolor(NUM_COLORS-4);
  2560.           outtextxy(NUM_X_PIXELS/2,NUM_Y_PIXELS-1,"Congratulations!");
  2561.           frequency=10;
  2562.           for (delta_index_1=1; delta_index_1 <= 100;
  2563.            delta_index_1++)
  2564.             {
  2565.               sound(frequency);
  2566.               delay(56);
  2567.               nosound();
  2568.               frequency+=10;
  2569.             };
  2570.           setcolor(0);
  2571.           outtextxy(NUM_X_PIXELS/2,NUM_Y_PIXELS-1,"Congratulations!");
  2572.           setcolor(NUM_COLORS-4);
  2573.           outtextxy(NUM_X_PIXELS/2,NUM_Y_PIXELS-1,
  2574.            "S - Solve    Other - Restart program");
  2575.           while (kbhit())
  2576.             {
  2577.               *key_pressed=getch();
  2578.               if (*key_pressed == 0)
  2579.                 {
  2580.                   *key_pressed=getch();
  2581.                   *key_pressed=(int) ' ';
  2582.                 }
  2583.             }
  2584.           *key_pressed=getch();
  2585.           if (*key_pressed == 0)
  2586.             {
  2587.               *key_pressed=getch();
  2588.               *key_pressed=(int) ' ';
  2589.             }
  2590.           setcolor(0);
  2591.           outtextxy(NUM_X_PIXELS/2,NUM_Y_PIXELS-1,
  2592.            "S - Solve    Other - Restart program");
  2593.         }
  2594.       return;
  2595.     }
  2596.